새로운 Action 추가 가이드라인
Posted on 2021-10-20 by GKSRUDTN99
Swift&Xcode
Xcode
Swift
RxSwift
새로운 Action 추가 가이드라인
1. Action에 관련된 State 속성을 State 구조체에 추가한다.
struct State {
var actionView = RevisionedData<ViewAction>(data:nil)
}
2. ViewController의 bind함수에 State를 UI에 바인딩한다.
func bind(reactor: Reactor) {
reactor.state.map{ $0.actionView }
.distinctUntilChanged()
.compactMap{ $0.data }
.asDriver(onErrorDriveWith: .empty())
.drive(onNext: { [weak self] view in
guard let self = self else { return }
switch view {
case .pushViewController(let vc):
self.navigationController?.pushViewController(vc, animated: true)
case .presentViewController(let vc):
self.present(vc, animated: false)
}
})
.disposed(by: disposeBag)
}
3. Mutate에 추가한 State를 다룰 수 있는 case를 추가하고, reduce 함수에도 이를 반영한다.
enum Mutation {
case setView(ViewAction)
}
func reduce(state: State, mutation: Mutation) -> State {
var newState = state
switch mutation {
case .setView(let type):
newState.actionView = state.actionView.update(type)
}
return newState
}
4. UI가 사용할 Action을 case에 추가하고, mutate 함수에 이를 반영한다.
enum Action {
case showSellerProfile
}
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .showSellerProfile:
let product = currentState.product
let vc = AppStoryboard.instantiate(.Common, with: UserProfileViewControllerV2.self)
vc.userId.accept(product.seller.id)
vc.partnerId.accept(product.seller.partnerId)
return .just(.setView(.pushViewController(vc)))
case .showDetailImages:
guard let images = currentState.productDescriptionImages else { return .empty() }
let vc = AppStoryboard.instantiate(.Home, with: ProductDetailImagesViewController.self)
vc.reactor = ProductDetailImagesViewReactor(images)
vc.modalPresentationStyle = .overFullScreen
return .just(.setView(.presentViewController(vc)))
case .updateCurrentPage(let page):
return .just(.setCurrentPage(page))
}
}
5. UI를 Action에 바인딩한다.
func bind(reactor: Reactor) {
userProfileButton.rx.tap
.map{ Reactor.Action.showSellerProfile }
.bind(to: reactor.action)
.disposed(by: disposeBag)
}