티스토리 뷰

iOS

[ReactorKit] ReactorKit의 transform

씌워터 2023. 9. 15. 18:27

ReactorKit에서 Reactor는 View에서 Action을 받는 것부터 시작해

Action -> Mutation -> Reduce(새로운 State할당)의 형태로 가게 된다.

 

그런데 Action이 일어나지 않았는데 State가 변경되어야 하는 일이 있을 것이다!!!

예를들어, 뷰가 아니라 어떤 알 수 없는 곳에서 상태가 바뀐다거나, 전역적인 상태가 바뀐다거나 등등..

 

이럴때 transform 함수를 사용한다.

func transform(action: Observable<Action>) -> Observable<Action>
func transform(mutation: Observable<Mutation>) -> Observable<Mutation>
func transform(state: Observable<State>) -> Observable<State>

처음엔 이걸보고 ..action으로 action을 만든다고..? 이런식으로 생각해서 좀 헷갈렸다

 

transform이 Reactor프로토콜 내부에 메서드로 정의되어 있는데

그 Reactor의 extension에 보면

// extension Reactor
public func transform(action: Observable<Action>) -> Observable<Action> {
    return action
}

public func mutate(action: Action) -> Observable<Mutation> {
    return .empty()
}

public func transform(mutation: Observable<Mutation>) -> Observable<Mutation> {
    return mutation
}

public func reduce(state: State, mutation: Mutation) -> State {
    return state
}

public func transform(state: Observable<State>) -> Observable<State> {
    return state
}

요렇게 되어있다.

 

예시로 mutation을 만들어주는 함수만 따로 빼서 보면 Mutation을 담은 옵저버블을 항상 받아서 그대로 리턴해주고 있다.

public func transform(mutation: Observable<Mutation>) -> Observable<Mutation> {
    return mutation
}

위 함수에서는 mutation을 그냥 그대로 리턴해주고 있지만,

만약 Mutation이 아니라 다른 외부에서 일어난 변경사항이 있는 경우, 여기서 따로 추가해서 기존의 mutation과 새로 관찰할 스트림을 merge를 이용해 합쳐주고 리턴해주면 되는 것이다. !!!!

 

ReactorKit의 Advanced => Global States 함수

currentUser가 변할 때 Mutation의 serUser를 호출하려는 예시이다. 여기서는  currentUser가 Action을 통해 변화하는걸 감지하는게 아니라 값이 변할때마다 BehaviorSubject가 값을 방출하고 이를 감지한다.

Observable.merge를 이용해서 두 스트림에서 방출되는 값을 합쳐주면 기본적으로 action -> mutation으로 가는 경우와 새롭게 정의한 Global state를 모두 리턴해줄 수 있다.

 

merge의 RX marble diagrams

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함