【Swift】RxSwift

主な特徴として、値変化の検知や非同期処理を簡単に書けるというものがある。UI変更の検知やAPIで取得した値の検知などが書きやすくなる。メソッドチェーンでかける。

例えば、以下の場合、ボタンが増えるに従い、IBActionも増えて可読性が低下する。RxSwiftなら、ボタンに対してタップした時の処理をプロパティとして定義するだけで済む。状況にもよるが、コンポーネントが複雑な画面はRxSwiftでの実装をした方がいい。また、@objc func...をaddTargetでコンポーネントで紐づけるより、こっちの方が良さそう。

@IBAction func tapButton(_ sender: Any) {
    label.text = "button tapped"
}

//viewDidLoad()の中で定義する
button.rx.tap
.subscribe(onNext: {[weak self] in 
    self?.label.text = "butoton tapped"
}).disposed(by: disposeBag)

RxSwiftの書き方は以下の通り。

  1. イベントの購読(ボタンのタップ、APIからのデータ取得などのストリームの購読)
  2. イベントを購読したときにどうするか定義
  3. クラスが破棄されると、購読も破棄される

主な用語

Observable...観測可能なものを意味する。イベントを検知するためのクラス。ストリームとも呼ばれる。Observableが通知するイベントは次の種類がある。

  • onNext...デフォルトのイベントを流す。イベント内に値を格納でき(下の例ではmessage)、何回でも呼べる。
  • onError...エラーイベント。1度だけ呼ばれる。その時点で終わり、購読を破棄する。
  • onCompleted...完了イベント。1度だけ呼ばれる。その時点で終わり、購読を破棄する。

以下では、onNextイベントが来るとそのクロージャが実行され、onErrorイベントが流れてくるとそのクロージャが実行され、onDisposedイベントが流れてくるとそのクロージャが実行される。

helloSubject // Observable(イベント発生元)
.subscribe(onNext: {message in 
    print(message) // Observer(イベント処理)
}, onError: { error in
    print(error)
},onCompleted: {
    print("onCompleted")
}, onDisposed: {
    print("onDisposed")
}).disposed(by: disposeBag)



// onError / onCompletedは省略できる
helloSubject.subscribe(onNext: {message in
    print(message)
}).disposed(by: disposeBag)

SubjectとRelay

イベントの検知に加えて、イベントの発生もできる。 以下の4つがある。

  • PublishSubject...oNext, onError, onCompleteを流せる。
  • BehaviorSubject...oNext, onError, onCompleteを流せる。
  • PublishRelay...oNextを流せる。
  • BehaviorRelay...oNextを流せる。

Subject・・・通信処理やDB処理でエラーが発生したときにその内容で処理を分岐させる。APIでデータをフェッチしたときに使う。
Relay・・・UIに値をBindする。購読が止まらないように、onNextだけ流せる。

bind

指定したものに、イベントストリームを接続する。単方向バインド。 下ではTextFieldに名前が入力された時、ViewModelに値を反映させる。

nameTextField.rx.text
.bind(to: viewModel.username)
.disposed(by: disposeBag)

参考サイト

qiita.com