RxSwift × MVVM
RxExample による Rx と MVVM
ViewControllerの役割
- Storyboard の UI コンポーネントをつなぐ
- ViewModel を初期化する
- ViewModel の出力と UI コンポーネントをバインドする
- その他の処理 (例)画面上のタップを検知し入力時のソフトウェアキーボードを閉じる
ViewModel の役割
- API 用のロジックなどをイニシャライザで外部から用意できるようにする
- イニシャライザで受け取った Observable を処理して出力に変換
ViewModel のイニシャライザで入力されたストリームは、出力のストリームに変換される→出力はストリームとして読み取られる
継承による disposeBag の保持
disposeBag はまとめて Observable を処分してくれる
disposeBag に Observable を持たせ、その disposeBag を破棄することで Observable をまとめて破棄できる
任意のタイミングでの dispose
disposeBag を使って ViewController の破棄と一緒に Observable をまとめて破棄するのが一般的
任意のタイミングで Observable を 破棄することもできる
subscribe メソッドの戻り値 Disposable インスタンスに対して dispose() メソッドを呼び出す方法がある
subscribe メソッドでは dispose されたことを購読でき、dispose さ れてからは以降のイベントは購読できなくなる
? .subscribeして.disposedする以外のパターン
IBOutlet から Observable の作成
ユーザ入力をイベントのストリームとして ViewModel へ伝えるため、IBOutlet な UI コンポーネ ントから Observable を作成する
usernameOutlet: UITextField!に対して、rx.text.orEmpty.asObservale() として メソッドを呼び出していき Observable<String>を取得
ViewModel の出力を View にバインド
ViewModel で処理したプレゼンテーションロジックは、出力のストリームとして View にバインディングしないといけない
viewModel.signupEnabled
.subscribe(onNext: { [weak self] valid in
self?.signupOutlet.isEnabled = valid
self?.signupOutlet.alpha = valid ? 1.0 : 0.5
})
.disposed(by: disposeBag)
subscribe メソッドの onNext クロージャでsignupEnabled ストリームの変化を Bool として取得するsignupOutlet: UIButton!の isEnabled および alpha プロパティにバインディングして変化させている
Observable を切り替える flatMapLatest
Observable を合成する combineLatest
最新の値を取得する withLatestFrom
まとめ
- Observable を共有せず購読した場合にその数だけ Observable のイベントが実行される
- 共有していない Observable は Cold Observable と呼ばれる
- Observable を共有することで実行の無駄を避けることが出来る
- 共有することによって Hot Observable と呼ばれる