はじめに
1つめの記事では、Observableの基本動作とイベントの受け取り側について説明しました。
本記事では、Observableの基本的な生成(イベントの発行側)について書きます。
動作もよりわかりやすくなると思います。
ここではSubjectについてはあまり触れずに、基本的な生成のみを書きます。
基本的なObservableの生成
Observableは、1章でのtextFieldの例のように、ライブラリ自体にいろいろなものが用意されていますので、ある場合はそれらを使うと良いですが、足りないときは自分で作る必要があります。
RxSwiftにはかなり多くの生成メソッドが存在します。一番の基本はcreateです。
create
Observable<Int>.create { observer in
observer.onNext(1)
observer.onNext(2)
observer.onCompleted()
return Disposables.create()
}
これは、subscribe()
すると、見た目通り?で
onNext(1) -> onNext(2) -> onCompleted
の順番でイベントを発行するObservableです。
observerパターンでは一般的なことですが、observerの onNext()
メソッドを呼び出すことで、イベントの通知を実現しています。(慣れてないと名前がややこしいですね)
Disposableについてはこの記事では触れませんが、大抵は Disposables.create()
で良いです。開放時に実行すべき処理や関連したdisposableなどある場合は、別途指定する必要があります(参考:Rx入門 (28) – Disposables名前空間まとめ)
just
1回のonNext(value)の直後にonCompletedを発行します
Observable.just(1)
onNext(1) -> onCompleted
試し書きなどにとても便利で、以下のような挙動をします。
Observable<Int>.create { observer in
observer.onNext(1)
observer.onCompleted
return Disposables.create()
}
型は値から類推されるので、Observable<Int>.just(1)
と書く必要はありません。(書いてもエラーではないです)
empty
onNextなしに、onCompletedのみ発行します
Observable<Int>.empty()
onCompleted
以下のような挙動です
Observable<Int>.create { observer in
observer.onCompleted
return Disposables.create()
}
emptyだと型が類推できないので、型が必要です。
error
emptyとは逆で、onError(error)のみ発行します。
Observable<Int>.error(error)
onError(error)
createで書き直すと、以下のような挙動です。
Observable<Int>.create { observer in
observer.onError(error)
return Disposables.create()
}
こちらも型が必要です。
never
何もイベントを発行しません。
Observable<Int>.never()
from
Array等をObservableに変換することができます。以下のようなものがあります。
array
Observable.from([1,2,3,4,5])
onNext(1) -> onNext(2) -> onNext(3) -> onNext(4) -> onNext(5) -> onCompleted
と流れてきます。sequenceを渡した場合も同じような挙動です。
createで書くなら以下のような感じでしょうか。
Observable<Int>.create { observer in
[1,2,3,4,5].forEach { i in
observer.onNext(i)
}
observer.onCompleted()
return Disposables.create()
}
optional
let a: Int? = nil
Observable.from(optional: a)
aがnilの場合はObservable.empty()、値がある場合はObservable.just(a!)のような動きをします
onCompleted()
or
onNext(a!) -> onCompleted()
filter, map, flatMapについては後で書きますが、
.filter { $0 != nil }
.map { $0! }
を
.flatMap { Observable.from(optional: $0) }
とできるのでとても便利です。
Subject
ここまでのObservableは一箇所に書くものばかりでしたが、
Subjectを使うと、より複雑なObservableを作ることができます。
例えば、以下のような感じです。
private let subject = PublishSubject<String>()
// getter
public var observable: Observable<String> {
return subject.asObservable()
}
func run() {
subject.onNext("foo")
subject.onCompleted()
}
Subjectは、外側からイベントを発行されないようにprivateにしておいて、observableのみを外部に公開することが多いです。
上の例ではPublishSubjectを使いましたが、SubjectにはBehaviorSubject, ReplaySubject等いろいろな種類があり、それぞれキャッシュなどについて、挙動が違います。
この記事では書きませんが、
タコさんブログ/RxSwift 入門 その2
などに詳しくまとめられていますので、参照ください。
標準実装で他にも
NotificationCenterやTimer、delegateなどをObservableとして取り出すことができるメソッドが用意されていますが、本記事では触れません。
また、 RxSwiftCommunity などを見ると、他にも様々なObservableが実装されていて、Carthageなどを通して利用することができます。