기본 개념(Basic Concept)
ReactorKit은 Reactive 및 단방향 플로우 아키텍처를 제공하는 프레임워크 중 하나이다.
아래 사진 처럼 Action과 View State는 Observable을 통해 전달받게 된다.
즉 View는 User Action에 대해 방출만을 할 수 있으며 Reactor는 State에 대해 방출만을 할 수 있다.
ReactorKit을 채택함으로써 얻는 효과는 다음 세 가지가 있다.
- Testability
- Start Small
- Less Typing
이유는 아래와 같다.
- View가 비즈니스 로직과 분리되어 구현
- Reactor는 View와 완전히 독립적인 개체로 존재
- 특정 몇개의 View에게 ReactorKit을 적용 가능 (기존 프로젝트 모든 코드를 다시 작성할 필요X)
- 다른 아키텍처들보다 코드가 간결하고 복잡하지 않다.
View
- iOS에서는 ViewController와 Cell과 같은 것들은 모두 View로 취급
- 비즈니스 로직은 View에 없음
- User Input은 Action Stream에 바인드하고 View States은 UI Component에 바인드
- View Class에 View라는 프로토콜을 채택하여 구현
- reactor라는 프로퍼티로 접근하여 Reactor를 주입
- reactor 프로퍼티가 변경되면 bind(reactor:)가 불려진다.
- 위 메서드를 이용하여 Action Stream, State Stream에 접근
Reactor
- UI와 독립적이고 State Stream을 관리
- 모든 View는 하나의 Reactor를 각각 가지고 있음
- Reactor라는 프로토콜을 채택하여 구현
- Action, Mutation, State를 정의해야함 initialState도 마찬가지
- Mutation은 Action과 State의 중간다리 역할
- Reactor는 Action → State 을 위해 mutate()와 reduce() 두 가지 Step을 거침
mutate()
- mutate()은 Action을 받아서 Observable<Mutation>을 만든다.
- 모든 비동기 처리나 API 요청 같은 Side Effect는 mutate() 메서드에서 로직을 수행한다.
reduce()
- reduce()는 이전의 State값과 Mutation을 받아서 새로운 State값으로 업데이트하는 메서드
- reduce()는 pure function이기 떄문에 오직 동기적으로 새로운 State값만을 return한다.
- 이 함수에서는 Side Effect가 발생할만할 로직을 수행해서는 안 된다.
transform()
- transform()은 각각의 Stream을 변환하는 역할을 하고, 총 세 가지의 함수가 있다.
- 이 함수들을 이용하면 다른 Observable Streams들을 변환하거나 병합할 수 있게 된다.
- 예를들어 transform(mutation:)은 글로벌 이벤트 Stream을 mutation stream으로 변환하기 적합하다.