SwiftUI+TCA+Combine

    [SwiftUI] - 자식뷰에 데이터를 어떻게 전달해야할까 그리고 뷰 갱신이 이루어 질까? with. MVVM

    회사 프로젝트는 정말 다양한 기술로 구성되어 있습니다. 많은 기술을 시도하고 공부하며 적용하고 더 좋은 구조를 찾아 발전하고 성장해나갑니다. UIKit, RxSwift, ReactorKit, RxFlow, SwiftUI, Combine, Asycn Await, MVVM, MVC등 많은 기술을 거쳐왔습니다.최근에는 SwiftUI와 MVVM을 주로 적용시켜왔습니다. UIKit을 사용 할 때에는 MVVM-InOut패턴과 RXSwift을 적용해 어느정도의 데이터 흐름을 파악하기 용이했습니다.Input을 정의해 이벤트가 어디서 시작되는지 알 수 있었고 스트림을 통해 방출되는 데이터는 Output을 활용해 뷰가 구독하고 갱신을 했습니다. 하지만 SwiftUI로 넘어오며 @Binding을 활용해 데이터의 양방향 흐름..

    [SwiftUI] ForEach가 View를 업데이트 하는 방법과 @StateObject를 사용할 때 문제점(그리고 그 뒷 이야기..)

    ++ 맨 아래를 참고해주세요 SwiftUI를 사용할 때 ForEach를 자주 사용합니다. 저는 회사에서 채팅 서비스를 개발하고있습니다. List를 사용할 수 있지만 List를 사용하는 방법보단ForEach + LazyVStack + ForEach를 사용하는 방법이 더욱 다양한 기능을 적용시키기 좋아서 후자를 선택해 사용하고있습니다. ForEach와 StateObject를 사용할 때에는 몇 가지 문제점이 있습니다.우선 ForEach는 View의 id를 기준으로 뷰를 구분하고 업데이트합니다.물론 @Published 프로퍼티가 바뀌게되어도 뷰를 업데이트 하긴 하죠. 하지만 @StateObject를 사용해 ForEach를 사용한다고 가정할 경우 뷰 업데이트에 대한 문제가 생길 수 있습니다. 만약 여러분이 채팅어..

    [SwiftUI] SwiftUI는 뷰를 어떻게 구분하고 업데이트 하는가.(Identity, Lifetime)

    SwiftUI는 뷰를 어떻게 구분하고 업데이트할까요? 또 Identity, Lifetime등 용어는 무엇일까요? 오늘은 이를 정리해보겠습니다. 우선 이를 알기위해 알아야 할 사전 지식이 있습니다. 동등성(equality)와 동일성(Identity)입니다. 동등성(Equality) 이 둘은 같을까요? Equatable로 비교하면 이 둘은 같습니다. 이렇게 상태만을 비교하면 이 둘은 같다고 할 수 있습니다. 동일성 한 clamp가 있다고 가정해봅시다. 우리는 이름도 같고, 나이도 같기 때문에 같은 clamp라고 생각 할 수 있습니다. 하지만 Equatable로 비교하면 다르다고 나옵니다. 상태가 다르니까요 만약 우리가 저 둘을 동일한 clamp라고 생각하려면, 즉 같은 clamp로 "식별"하려면 무언가가 필..

    SwiftUI TCA - 3. State, Action, Reducer, Effect

    TCA의 구성을 하나 씩 살펴보겠습니다. 앱의 상태 "State" State는 Reducer의 현재 상태를 갖는 구조체입니다. 쉽게 비즈니스 로직을 수행하거나 UI를 그릴 때 필요한 데이터를 소지합니다. 예를 들어 카운트를 증, 감 시키는 어플리케이션을 가정합니다 그럼 카운트를 표시하기위해 State는 다음과같이 count데이터를 소지하고 있을 것 입니다. struct CounterFeature: Reducer { struct State: Equatable { var count = 0 } ... } 여기서 State는 Equatable인데요, 그 이유는 다음과 같습니다. SwiftUI는 View의 상태가 변경되었을 때 해당 view를 자동으로 업데이트 합니다. 즉 현재 상태와 이 전 상태를 비교하여 불 ..

    SwiftUI TCA - 2. 단방향 아키텍처 TCA

    TCA는 단방향 아키텍처입니다. 하지만 SwiftUI는 양방향 데이터 바인딩을 지원합니다. View가 ViewModel에서 요청을 받아와서 추가작업을 해야하는 경우가 발생합니다. 이런 상황에 팀원과의 협업중 코드 작성에 유의하지 않는다면 나중에 언제 어디서 상태가 바뀌는지 알기 파악하기 어려운 문제가 생길 수 있습니다. 이와달리 TCA의 상태 변화에 대한 일관적인 가이드라인을 컴파일 단계에서부터 강제합니다. 어떠한 개발자던 TCA를 사용한다면 Action 정의, Action에대한 View에서의 .send() 를 거쳐야합니다. 이러한 규칙을 적용할 수 있습니다. TCA의 핵심은 다음과 같습니다. 1. State management(상태 관리): 상태를 공유하는 방법. 이를 통해 특정 화면에서의 상태변화를 ..

    SwiftUI TCA - 1. TCA의 등장 배경

    애플 생태계 개발은 주로 Swift로 많이 작성됩니다. 이렇게 작성된 코드들의 관리 방법또한 중요합니다. 3일뒤, 3주뒤, 3달뒤에 코드를 돌아볼 때 어느 파일에 어느 코드가 있을지 알아야 유지보수에 용이하기 때문입니다. 코드를 정리하고 구현하는데에는 일정한 규칙이 있습니다. 정형화된 하나의 규칙을 제안하는것 = '디자인 패턴(Design Pattern)' 정리된 코드들을 더 추상화된 비즈니스적 문제 해결 관점으로 정리하는것 = '아키텍처 패턴(Architecture Pattern)' 여기선 상태관리 및 의존성 라이브러리인 The Composable Architecture를 활용한 아키텍쳐 패턴에 대해 정리합니다. 기존의 패턴 Swift, SwiftUI로 선언형 UI를 구현하는 환경에서는 MVVM패턴이 ..

    SwiftUI - @ObservableObject, @ObservedObject, @Published, ObjectWillChange

    @ObservableObject @ObservedObject는 ObservableObject 프로토콜을 준수하는 객체를 관찰하는 뷰 내에서 사용되는 프로퍼티 래퍼입니다. ObservableObject는 Class형태만 가능합니다. Struct형태는 불가능합니다. class의 @Published 인스턴스의 변화를 감지하고 해당 인스턴스가 변화할 때 마다 뷰를 업데이트합니다. ObservableObject 프로토콜을 준수하면 objectWillChange프로퍼티를 사용할 수 있습니다. * @Published 어노테이션은 값이 변동되었을때 바로 View에게 즉각적으로 알려주는 어노테이션입니다. ex) class MyViewModel: ObservableObject { @Published var score =..

    SwftUI - @State, @Binding

    @State와 @Binding은 모두 데이터의 서유와 공유 방식을 다루는 두가지 property wrapper입니다. @State 뷰 내에서 private 상태를 관리하기위한 프로퍼티 래퍼입니다. 뷰 내부 상태를 저장하기위해 사용됩니다. 해당 프로퍼티 래퍼로 생성된 변수의 상태 변경시 뷰가 자동으로 업데이트되게합니다. ValueType으로 Struct, Enum 활용이 적절합니다. @State프로퍼티 값이 변경될 때 마다 뷰를 다시 랜더링합니다. 최신 상태를 유지하도록. 여기서 $가 등장합니다. Toggle의 isOn값은 Binding 값을 받으므로 $를 붙혀 초기화합니다. isOn -> Bool값 $isOn -> Binding @Binding 부모뷰로부터 전달받은 상태 또는 다른뷰와의 상태를 공유하기위..

    PropertyWrapper의 projectedValue

    프로퍼티래퍼에대한 정보는 아래 포스팅에 정리되어있습니다. https://clamp-coding.tistory.com/396 projectedValue SwiftUI에서 @State, @Binding, @Published등의 프로퍼티 래퍼들은 각각의 *projected value(투영값)을 가집니다. 이 투영값은 프로퍼티 래퍼가 제공하는 추가 기능에 접근할 수 있도록 해주는데, 특히 바인딩이나 다른 형태의 상태관리를 위한 인터페이스 역할을 합니다. 이는 SwiftUI가 관리하는 변수의 "특별한 버전"을 의미합니다. 해당 변수를 UI컴포넌트와 연결하거나 변수의 변화를 감시하는 등의 추가적인 작업을 할 수 있게 됩니다. ProjectedValue는 해당 프로퍼티의 "추가기능"에 접근할 수 있는 방법입니다. '..