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를 전달하거나 전달받지 않는다.