RxSwiftCommunity 에서 하는 프로젝트

24(+2)개의 연산자를 제공하는데 아래에는 일부 연산자만 정리했다.

distinct

일련의 값에서 중복을 제거할 때 사용한다.

_ = Observable.of("a", "b", "a", "c", "b", "a", "d")
  .distinct()
  .toArray()
  .subscribe(onNext: { print($0) })
["a", "b", "c", "d"]

mapAt

Keypaths를 활용하여 데이터를 추출할 때 사용한다.

struct Person {
    let name: String
}

Observable
  .of(Person(name: "Bart"),
      Person(name: "Lisa"),
      Person(name: "Maggie"))
  .mapAt(\.name)
Bart
Lisa
Maggie

retry, repeatWithBehavior

시퀀스가 완료되거나 오류가 발생하면 시퀀스를 다시 구독하는 동시에 재구독이 발생하는 방법과 시기를 제어한다.

다음 열거형 중 하나를 사용하여 지정한다.

  • .immediate(maxCount:) → 최대 maxCount번까지 즉시 구독한다.
  • .delay(maxCount: UInt, time: Double) → 동일하지만 초 단위로 지연시킨다.
  • .exponentialDelayed(maxCount: UInt, initial: Double, multiplier: Double) → 매 주기마다 재구독 지연을 곱한다.
  • .customTimerDelayed(maxCount: UInt, delayCalculator: (UInt) -> Double) → 현재 반복을 수신하고 재구독이 지연되어야 하는 시간(초)을 반환하는 클로저를 제공한다.
// 요청을 최대 3회 시도한다.
// 각 시도에서 지연 시간을 3초 곱한다.
// 그래서 1, 3, 9초 후에 다시 시도한다.
let request = URLRequest(url: url)
let tryHard = URLSession.shared.rx.response(request: request)
  .map { response in
      // process response here
}
  .retry(.exponendialDelayed(maxCount: 3, inital: 1.0,
multiplier: 3.0))

catchErrorJustComplete

오류를 무시하고 싶을 때 사용하는 연산자다.

let neverErrors = someObservable.catchErrorJustComplete()

withUnretained

주어진 객체에 대한 약한 참조를 유지하고 시퀀스가 무언가를 방출할 때마다 여전히 존재하는 지 여부를 테스트한다. 객체가 여전히 참도되는 경우 전달한 클로저가 실행되고, 반환되는 값은 새로 내보낸 값이다.

var anObject: SomeClass! = SomeClass()
_ = Observable.of(1, 2, 3, 5, 8, 13, 18, 21, 23)
  .withUnretained(anObject)
  .debug("Combined Object with Emitted Events")
  .do(onNext: { _, value in
      if value == 13 {
        // anObject가 nil이 되면, 새로운 값으로 넘어간다.
        // 시퀀스가 실패하면... 완료된다.
        anObject = nil
        }
    })
  .subscribe()

이 연산자는 guard let self = self 를 피하면서 안전하게 self 를 캡처하려고 할 때 유용하다.

message
  .withUnretained(self) { vc, message in
    vc.showMessage(message)
  }

그리고 RxSwift 6부터 공식적으로 포함되었다.

partition

조건에 따라 스트림을 두 개의 스트림으로 분할할 때 사용한다.

let (evens, odds) = Observable
                      .of(1, 2, 3, 5, 6, 7, 8)
                      .partition { $0 % 2 == 0 }
_ = evens.debug("evens").subscribe() // Emits 2, 6, 8
_ = odds.debug("odds").subscribe() // Emits 1, 3, 5, 7

mapMany

컬렉션 타입의 시퀀스 내부의 모든 개별 요소를 매핑한다.

_ = Observable.of(
  [1, 3, 5],
[2, 4] )
.mapMany { pow(2, $0) }
.debug("powers of 2")
.subscribe() // Emits [2, 8, 32] and [4, 16]