공식 github
개요
기존에는 MVVM 아키텍처 패턴을 사용했으나, 구현해야할 기능이 늘어나면서 과연 ViewModel이 코드를 작성하는데 도움이 되는가 하는 의문이 생겼다.
비즈니스 로직이 담기는 만큼 ViewModel의 규모가 커지고, 같은 데이터를 뷰와 뷰 모델 양쪽에서 접근하고 제어할 수 있다는 점에도 의문이 들었다. View에서 @State와 @Binding 프로퍼티 래퍼를 사용해 데이터에 접근할 수 있는데 굳이 ViewModel을 거쳐서...?
SwiftUI가 지향하는 데이터의 단방향 플로우와는 사뭇 다르다.
MVVM vs TCA 작동 방식 비교
MVVM 작동 방식
그렇다고 View에 모든 로직을 다 작성한다면 View가 복잡해지고 방대해질 뿐더러, 비록 화면과 연관된 로직이기는 하나 화면을 구성하는 코드에 로직이 포함된다는 게 마음에 들지는 않았다.
TCA 작동 방식
TCA 구성 요소
- State
비즈니스 로직을 수행하거나 UI를 그릴 때 필요한 데이터의 집합. 기존에 @State로 감싸인 데이터 변수라고 생각하면 편하다. - Action
사용자에 의해 뷰에서 발생하는 모든 action과 API호출 결과를 나타내는 타입. - Dependency
API 클라이언트를 비롯한 외부 시스템과 같이 어플리케이션이 필요로 하는 의존성(Dependency)을 가지고 있는 타입. UUID나 Date의 초기화등도 포함. - Effect
네트워크 요청, 디스크에서 저장/로드, 타이머 생성, Dependency와 상호 작용과 같은 작업을 수행하는Reduce()
의 리턴값. 통신의 결과라고 생각하면 편하다. - Reduce
Action을 전달받아 이를 처리한 결과로 State의 상태를 변경해 UI를 업데이트하는 로직.
API 요청과 같은 이벤트를 Effect와 Dependency를 이용해 실행하고, 실행한 결과는 Action으로 다시 Reducer에 전달된다. - Store
실제로 기능이 작동하는 공간(공식 문서에는 runtime이라 표현한다). Action을 트리거로 Store는 Reducer와 Effect를 실행할 수 있고, 이로 인해 Store에서 일어나는 State 변화로 UI를 업데이트한다.
구성 요소의 흐름
- 사용자는 View를 통해 Action을 생성하고, 생성된 Action은 Reducer로 삽입된다. (앱 내 간단한 로직 처리(통신이 필요없는)가 가능하면 Reducer -> State 도 가능)
- Reducer가 Dependency를 실행하고 그 결과를 Effect 타입으로 반환. Effect는 통신의 결과이며, 개발자가 의도하지 않는 Effect는 Side Effect라 칭한다
- 모든 Effect 각각을 Action으로 받아, 다시 Reducer에 넘겨 로직을 실행한다.
Tutorial
표시된 숫자를 + 버튼 , - 버튼을 눌러 값을 변경해보자
먼저 프로젝트 swift-composable-architecture 패키지를 추가한다.import ComposableArchitecture
로 사용.
구현 순서는 공식 튜토리얼을 따라감
Reducer 구현
@Reducer 매크로를 사용해 구조체를 선언한다. 해당 Struct는 Reducer 프로토콜을 준수한다.
위 TCA 구성요소에서 살펴봤던 State와 Action을 확인할 수 있다. 이때 State는 반드시 Equatable 프로토콜을 준수해야한다.
body에서 Reducer가 State와 Action을 인자로 받아. 특정 action으로 특정 state를 변경하는 것을 확인할 수 있다.
SwiftUI View 구현
SwiftUI를 사용해 뷰 컴포넌트를 구현한다. 이때 store를 let
으로 선언하는 부분에서 데이터의 단방향 플로우를 엿볼 수 있다. View에서는 Action만 Reducer에 보낼 뿐 State를 직접 변경할 수 없다.
State 값 추적
Reducer는 ._printChanges()
라는 유용한 디버깅용 메서드를 가지고 있다. 이 메서드는 Reducer가 진행하는 모든 Action과 그에 대한 State 변화를 콘솔에 찍어준다.
결과
잘못된 개념이나 오탈자는 댓글로 부탁드립니다.
참고
https://medium.com/naverfinancial/네이버페이-워치앱-tca-적용기-655f1d1b8c23
'iOS' 카테고리의 다른 글
[iOS] [Swift] 리프레시 토큰 도입기 (0) | 2023.12.16 |
---|---|
[SwiftUI] [Combine] [MVVM] Apple OAuth 소셜 로그인 구현하기 (0) | 2023.12.16 |