RxSwift
RxJava 이후 간단하게 정리
RxSwift with MVVM
- 뷰에 들어가는 요소: RxCocoa 요소, UI 컨트롤들, 뷰모델
- 뷰모델에 들어가는 요소: 릴레이
- 행동 -> 뷰가 릴레이를 구독, 이벤트가 방출되면 행동을 실행하도록 바인드
map, flatMap, flatMapLatest
- map: 이벤트의 타입을 바꾸면서 그대로 다시 구독할 수 있다.
- flatMap: 다른 옵저버블을 만들면서 배출할 수 있다. 상위 옵저버블에서 내려온 값을 계속 관찰한다.
- flatMapLatest: 옵저버블을 리턴하되, 마지막 값만 가지고 있는다.
에러 처리
- 더이상 새로운 이벤트를 처리할 수 없게 됨(옵저버블이 닫혀버림, 구독 종료)
- catchError에서 새로운 옵저버블을 리턴하는 방법으로 처리할 수 있음
- 네트워크의 경우 기본값, 로컬 캐시 등을 전달하는 방법으로 처리
- 아니면 다시 구독하는 방법(retry, 무한정 또는 재시도 할 수 있음)
catchError
let subject = PublishSubject<Int>()
let recovery = PublishSubject<Int>()
subject
.catchError { _ in
return recovery // 에러가 난 서브젝트를 다른 서브젝트로 교체
}
.subscribe { print $0 }
.disposed(by: disposeBag)
subject.onError(error) // 옵저버블이 닫힘
catchErrorJustReturn
let subject = PublishSubject<Int>()
subject
.catchErrorJustReturn(-1) //기본값을 방출하고 complete시킴
.subscribe { print $0 }
.disposed(by: disposeBag)
subject.onError(error) // 옵저버블이 닫힘
retry
let subject = PublishSubject<Int>()
subject
.retry(2) // 시도 횟수를 지정해서 한번 더 실행, 최대 횟수에 도달하면 complete
.subscribe { print $0 }
.disposed(by: disposeBag)
subject.onError(error) // 옵저버블이 닫힘
retryWhen
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Int>()
subject
.retryWhen { _ in trigger } // 원래 서브젝트를 다시 구독하지만, trigger에서 이벤트를 방출해야 다시 구독이 시작됨
.subscribe { print $0 }
.disposed(by: disposeBag)
subject.onError(error) // 옵저버블이 닫힘
바인딩
- RxCocoa에서 바인더는 다른 옵저버블을 구독, 데이터를 표시한다.
- 바인더를 구독할 수는 없다.
- 레이블, 텍스트뷰(바인더): 데이터 소비자로 이해, 바인더는 에러를 받지 않는다.(에러를 받으면 연결이 끊어지니까 막아둠)
- 옵저버블: 데이터 생산자로 이해
- 바인더는 메인스레드를 보장한다.
let textField: UITextField!
let label: UILabel!
textField.rx.text // 얘가 옵저버블
.subscribe(onNext: {[weak self] in // 일반적인 onNext 구독, 여기서는 메인UI가 보장되지 않는다.
self?.label.text = str // next를 받을때 일어나는 일을 클로저로 전달
)}.disposed(by: bag)
textField.rx.text
.bind(to: label.rx.text) // 다른 옵저버(바인더 타입)에게 전달
.disposed(by: bag)
Traits
- RxCocoa에서 제공하는 UI 전용 객체
- 에러를 일으키지 않는다.
- 제거되기 직전에 completed가 호출된다.
- Control Property의 경우 share에 replay(1)이 걸린것처럼 새로 구독한 구독자에게 다른 구독자와 똑같은 이벤트를 하나 전달해 준다.
- Control Event는 똑같이 share하나 구독했다고 이벤트가 전달되는 것은 아니다.
Driver
- RxCocoa에서 제공하는 특별한 옵저버블
- 에러메세지를 뱉지 않는다.
- 메인 스케줄러에서 전달을 보장한다.
- share되는 특성이 있으며, 새로 구독시에 또같이 하나를 replay받는다.
- asDriver()로 에러를 처리하는 방법을 구현할 수 있다.
Relay
- Subject를 맵핑하는 옵저버블, 옵저버이다.
- RxCocoa, RxRelay(RxSwift 내 존재)에서 제공한다.
- Error와 Complete를 전달하거나 전달받지 않는다.