LoginSignup
80
61

More than 3 years have passed since last update.

RxSwiftについてようやく理解できてきたのでまとめることにした(2)

Last updated at Posted at 2017-08-24

はじめに

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などを通して利用することができます。

続き→RxSwiftについてようやく理解できてきたのでまとめることにした(3)

80
61
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
80
61