タコさんブログ

プログラミングメモと小言

RxSwift 入門 その6

RxSwift 入門 その5 - タコさんブログ の続き。
今回は、RxSwiftプレイグラウンドの Error Handling OperatorsObservable Utility OperatorsConditional and Boolean Operators の項。

Error Handling Operators

この項では、Observableからのエラー通知から復帰するのに役立つオペレータに関して説明してある。

以下、プレイグラウンドに説明してあるError Handlingに関するオペレータ。

  • catchError
  • retry

catchError

catchErrorオペレータは、エラーなしでシーケンスを継続することによってエラー通知から復帰する。

let s = PublishSubject<Int>()

_ = s
  .catchError { error in
    return [10,11,12].toObservable()
  }
  .subscribe {
    print($0)
  }

s.on(.Next(1))
s.on(.Next(2))
s.on(.Next(3))
s.on(.Error(NSError(domain: "Test", code: 0, userInfo: nil)))

この出力は、

Next(1)
Next(2)
Next(3)
Next(10)
Next(11)
Next(12)
Completed

このマーブルダイアグラムは以下のように表せられる。

-1-2-3-x
      -10-11-12|
 ↓ 結果
-1-2-3-1-1-1|
       0-1-2|

retry

retryオペレータは、ソースObservableがエラーを送信したら、再度サブスクライブする。

以下の例は、bad practice とコメントしてある通り、例を示すためだけのもの。

var counter = 1
let stream = Observable<Int>.create { observer in
  observer.on(.Next(0))
  observer.on(.Next(1))
  observer.on(.Next(2))
  // エラーを故意に起こす
  if counter < 2 {
    let error = NSError(domain: "Test", code: 0, userInfo: nil)
    observer.on(.Error(error))
    counter += 1
  }
  observer.on(.Next(3))
  observer.on(.Next(4))
  observer.on(.Next(5))
  observer.on(.Completed)

  return NopDisposable.instance
}

_ = stream
  .retry()
  .subscribe {
    print($0)
}

この出力は、

Next(0)
Next(1)
Next(2)
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Completed

このマーブルダイアグラムは以下のように表せられる。

-0-1-2-x
        -0-1-2-3-4-5|
 ↓ 結果
-0-1-2-0-1-2-3-4-5|        

Observable Utility Operators

この項では、Observableを操作するのに役立つオペレータ、subscribeオペレータとわずかに異なるオペレータに関して説明してある。

以下、この項で説明してあるオペレータ。

  • subscribe
  • subscribeNext
  • subscribeCompleted
  • subscribeError
  • doOn

subscribe

おなじみのsubscribeオペレータ。
subscribeオペレータはobserverとobservableを結びつけるのりとなるオペレータ。 おなじみなので例は省略する。

subscribeNext, subscribeCompleted

subscribeNextは、Observableにエレメントハンドラをサブスクライブするオペレータ。Observableがアイテム(イベント)を送信するときに呼ばれる。

subscribeCompletedは、Observableにコンプリーションハンドラをサブスクライブするオペレータ。エラーが起こっていない場合、Observableが最後のアイテムを送信した後にコンプリーションハンドラが呼ばれる。

let stream = PublishSubject<Int>()
  // Nextをサブスクライブ  
_ = stream
  .subscribeNext {
    print($0)
  }
  // Completedをサブスクライブ
_ = stream
  .subscribeCompleted {
    print("Completed")
  }

stream.on(.Next(1))
stream.on(.Completed)

この出力は、

1
Completed

subscribeError

subscribeErrorは、Observableにエラーハンドラをサブスクライブするオペレータ。

let stream = PublishSubject<Int>()
_ = stream
  .subscribeError { error in
    print("Error:", error)
  }

let error = NSError(domain: "Examples", code: -1, userInfo: nil)
stream.on(.Error(error))

この出力は、

Error: Error Domain=Examples Code=-1 "(null)"

doOn

doOnオペレータは、いろいろなObservableのライフサイクルイベント(Next, Complete, Error)に応じるためにアクションを登録する。

let stream = (0...6).toObservable()
_ = stream
  .doOn {
    print("インターセプトされたイベント \($0)")    
  }.filter {
    $0 % 2 == 0
  }.subscribe {
    print($0)
  }

この出力は、

インターセプトされたイベント Next(0)
Next(0)
インターセプトされたイベント Next(1)
インターセプトされたイベント Next(2)
Next(2)
インターセプトされたイベント Next(3)
インターセプトされたイベント Next(4)
Next(4)
インターセプトされたイベント Next(5)
インターセプトされたイベント Next(6)
Next(6)
インターセプトされたイベント Completed
Completed

Conditional and Boolean Operators

この項では、いくつかのObservablesによって送信される1つ以上のObservables、または、アイテム(イベント)を評価するオペレータに関して説明してある。

以下、この項で説明してあるオペレータ。

  • takeUntil
  • takeWhile

takeUntil

takeUntilは、2番目のObservableがアイテムを送信、または終了した後に、一番目のObservableから送信されたアイテムを破棄する。

let s1 = PublishSubject<Int>()
let s2 = PublishSubject<Int>()

_ = s1
 .takeUntil(s2)
 .subscribe {
   print($0)
 }

s1.on(.Next(1))
s1.on(.Next(2))
s1.on(.Next(3))
s1.on(.Next(4))

s2.on(.Next(1))

s1.on(.Next(5))

この出力は、

Next(1)
Next(2)
Next(3)
Next(4)
Completed

このマーブルダイアグラムは以下のように表せられる。

s1 -1-2-3-4---5-
s2        -1--
 ↓ takeUntil s2
r  -1-2-3-4-|

takeWhile

takeWhileは、指定された条件が偽となるまでObservableから送信されたアイテム(イベント)を反映する。

let stream = (0..<10).toObservable()

_ = stream
  .takeWhile { x in
    x < 4
  }
  .subscribe {
    print($0)
  }

この出力は、

Next(0)
Next(1)
Next(2)
Next(3)
Completed

このマーブルダイアグラムは以下のように表せられる。

-0-1-2-3-4-5-6-7-8-9|
 ↓ takeWhile { x < 4 }
-0-1-2-3|

参考URL

Error Handling operators

Observable Utility Operators

Conditional and Boolean Operators