RxSwiftにおけるObserverパターン(2)
Observableオブジェクトを生成する
前項で触れた、監視可能なObservableオブジェクトを生成する方法について解説します。説明は次節以降になりますが、RxSwiftではUIなどからすぐに利用できるObservableも存在し、RxSwiftの導入当初は開発者自身がObservableを生成して利用することは少ないです。ここでは、Observableオブジェクトを生成する方法を簡単に説明します。Observableオブジェクトを生成するメソッドには、次のものがあります。
of | 一定数の要素でObservableを作成 |
from | 配列/辞書/集合などからObservableを作成 |
create | Observableをゼロから作成 |
never | イベントを終了しないObservableを作成 |
empty | completedイベントのみを発生するObservableを作成 |
String型の値を持つObservableオブジェクトは、ofメソッドを利用して次の通り生成できます。
let helloObservable : Observable<String> = Observable.from(["H","e","l","l","o"])
Stringの値は"H","e","l","l","o"の順番で変わります。生成したObservableオブジェクトをsubscribe(_:)メソッドを利用して監視する処理は次のように記述できます。
// Observableを生成 let helloObservable : Observable<String> = Observable.from(["H","e","l","l","o"]) // 監視 let subscription = helloObservable.subscribe( // -------(1) onNext: { value in print(value) }, onError: { error in print(error.localizedDescription) }, onCompleted: { print("completed") } ) // 完了時に解放 let disposeBag = DisposeBag() // -------(2) subscription.disposed(by: disposeBag)
(1)subscribe(_:)メソッドでonNext/onError/onCompletedの処理を指定してObservableオブジェクトを監視します。onNextで変化した値を出力、エラー発生時にはエラー内容を出力、完了時には「completed」を出力します。
(2)subscribe(_:)メソッドの戻り値のDisposableオブジェクトをdisposed(by: )メソッドで解放します。その際に廃棄フラグ的な役目を果たすDisposeBagオブジェクトを渡します。DisposeBagオブジェクトは同じものを使いまわすことができますので、ビューコントローラーの上部で生成しておいても構いません。
サンプルを実行すると、次の通り変化したStringの値が順番に表示され、最後に「completed」が出力されます。
H e l l o completed
Stringの値が変わった場合と処理が完了した場合に各イベントが発生し、通知されていることがわかります。実行中にエラーが発生した場合は、そのエラー内容が表示されます。
Observableオブジェクトでは、メソッドを連続して記述するメソッドチェーンの記述も利用できます。メソッドチェーンを利用するとサンプルは次の通り記述することが可能です。
helloObservable.subscribe( onNext: { value in print(value) }, onError: { error in print(error.localizedDescription) }, onCompleted: { print("completed") } ).disposed(by: disposeBag)
subscribe(_:)メソッドの戻り値であるDisposableオブジェクトはオブジェクトの解放以外に利用しないので、変数に代入せずに続けてdisposed(by: )メソッドを記述しています。
また、Observableクラスは次のObserverTypeプロトコルを実装しています。
protocol ObserverType { func on(_ event: Event<Element>) }
プロトコルの書式の通り、on(_:)メソッド内でイベントを指定することでnext(Element)/error(Swift.Error)/completedの各イベントで何をするか定義してObservableを生成することも可能です。
let exampleObservable : Observable<String> = Observable.create { (observer) in observer.on(.next("Hello")) observer.on(.completed) observer.onError(NSError(domain: "My Observable Error", code: -1, userInfo: nil)) return Disposables.create() }
各イベントを定義した後に、購読を解除するDisposableオブジェクトを返却します。作成したexampleObservableオブジェクトも前のサンプルと同様にsubscribe(_:)メソッドで動作確認できます。
exampleObservable.subscribe( onNext: { print($0) }, onError: { print($0.localizedDescription) }, onCompleted: { print("completed") } ).disposed(by: disposeBag) // 実行結果「Hello」「completed」 を出力
onNext/onErrorのクロージャ内に渡される値は、記述を省略して上記のように「$0」で取得できます。簡単なサンプルですが、Observableオブジェクトの生成と確認はこのようにして行います。開発者自身がObservableオブジェクトを生成するケースは、APIからのJSONの取得やDBからの値の取得など非同期で実行され、かつエラーが起きる可能性がある場合などによく利用されます。