TCA(The Composable Architecture)
단방향 플로우 아키텍쳐로 흔히 알고 있는 ReactorKit과 매우 비슷하다.
TCA의 구성요소
- State: 비즈니스 로직을 수행하거나 UI를 그릴 때 필요한 데이터에 대한 설명을 나타내는 타입.
- Action: 사용자가 하는 행동이나 노티피케이션 등 어플리케이션에서 생길 수 있는 모든 행동을 나타내는 타입. View를 통해 액션 발생시킴.
- Reducer: 어떤 행동(Action)이 주어졌을 때 지금 상태(State)를 다음 상태로 변화시키는 방법을 가지고 있는 함수. 또한 리듀서는 실행할 수 있는 이펙트(Effect, 예시: API 리퀘스트)를 반환해야 하며, 보통은
Effect
값을 반환. Effect는 다른 Action을 트리거할 수 있다. - Store: 실제로 기능이 작동하는 공간. 사용자 행동(Action)을 보내서 스토어(Store)는 리듀서(Reducer)와 이펙트(Effect)를 실행할 수 있고, 스토어(Store)에서 일어나는 상태(State) 변화를 관측(observe)해서 UI를 업데이트할 수도 있다.
- Environment: API 클라이언트나 애널리틱스 클라이언트와 같이 어플리케이션이 필요로 하는 의존성(Dependency)을 가지고 있는 타입.
TCA와 SwiftUI를 사용하여 간단한 데모앱 만들어보기
간단한 숫자 카운팅 앱을 만들어 보자.
- 우선 TCA를 사용하려면 Xocde에 패키지를 추가해야한다(SPM만 지원함).
TCA GitHub: https://github.com/pointfreeco/swift-composable-architecture - TAC의 핵심인 Recuder를 만들어보자!
- Recuder 프로토콜은 채택한 뒤에 State, Action 을 구현하고, reduce메서드도 구현한다.
- State는 Int형 변수를 갖고 변화하는 숫자를 count에 저장한다.
- Action은 증가와 감소 두개의 액션을 정의
- reduce 메서드에 각 액션에 따라 State값을 변경하는 로직을 넣어준다. 각 액션의 결과로 어떠한 사이드 이펙트도 실행이 필요하지 않기 때문에 .none 을 반환한다.
만약 각 액션에 API호출과 같은 사이드 이팩트가 필요하다면 Effect<Action>으로 추상화 필요함.
3. View 그리기
- View에 Reducer를 채택한 CounterReducer 타입의 store를 선언하고 body 내부에서 WithViewStore를 사용하여 이름 그대로 뷰에 Store를 사용하여 View의 액션과 Store의 액션을 연결하고 Store의 State를 관찰하여 뷰를 그리도록 해준다.
- ContentView가 수정되었으니 main쪽도 수정해보자.
ContentView의 store를 초기화하여 의존성을 주입하도록 수정한다. - _printChanges() 메서드는 디버그 모드에서 로그를 남기는 역할을 한다.
참고
https://gist.github.com/pilgwon/ea05e2207ab68bdd1f49dff97b293b