RxSwift初心者でも挑戦できる今すぐできるRxSwift例
自分が初めてRxSwiftを書き始めた時を思い出しながら、最初に学んだRxSwiftの事例をまとめてみた。
基本的にBindはviewDidLoad
の中で呼ぶ!ViewModelなどの場合はinit()
で呼ぶのが良い。
TextFieldをバインド
rx_text
とsubscribeNext {}
を使ったtextField
のバインド
この組み合わせでtextFieldのtextが更新されるたびにsubscribeNext
の引数を使って処理できる。
UITextFieldDelegate
を使わずにTextFieldの更新を検知できる。
UITextView
でも同じ事ができる。
textField.rx_text
.subscribeNext { [weak self] text in
print(text)
}
.addDisposableTo(disposeBag)
例えば何ができるのか!
username
を入力する画面で決定ボタンをTextFieldに5文字以上入力されたら有効になるようにしたい。
textField.rx_text
.subscribeNext { [weak self] text in
self?.sendButton.enabled = text.characters.count > 5
}
.addDisposableTo(disposeBag)
ここにbindTo()
を使ってちょっと進化させよう
textField.rx_text
.map { $0.characters.count > 5 } //ここで5文字以下なら`false`それ以外は`true`
.bindTo(sendButton.rx_enabled)
.addDisposableTo(disposeBag)
この4行でUITextFieldDelegate
を使ってメソッドを使わないと実装できないことが実装できるようになります!
UIButtonをバインド
'rx_tap'と'subscribeNext'を使ったバインド
'rx_tap'を利用すれば@IBActionを利用しなくてもタップを検知し、その時に処理を実行できる!
button.rx_tap
.subscribeNext { _ in
print("Hello World")
}
.addDisposableTo(disposeBag)
これだけでタップされた時に特定の処理を実行できます。
ついでに、ボタンを押した時にAPI通信をするときなど、短い間での複数タップを防ぎたい時!
RxSwiftにはdebounce
/throttle
というオペレーターが用意されていて、これを使うと
以下のように0.5秒間内のタップをフィルターしたりできます!
button.rx_tap
.throttle(0.5, MainScheduler.instance)
.subscribeNext { _ in
print("Hello World")
}
.addDisposableTo(disposeBag)
ではボタンを押したらAPI通信をして、そのレスポンスで何かしたい場合はどうするか。
flatMap
を使ってボタンのストリームをAPIのレスポンスのストリームに変えてあげる。
ここは僕も理解するのに時間がかかりました⇦
button.rx_tap
.throttle(0.5, MainScheduler.instance)
.flatMap { _ -> Observable<Model> in // Modelはresponseの型
return API.request() //ここは自前で用意する!レスポンスをObservableで返すRxのExtensionが必要かも
.catchError { _ in Observable.empty() }
// エラーが流れてくると購読を終了してしまうので、empty()を返す必要がある
}
.subscribeNext { response in
// ここでresponseが引数で使える
print("Hello \(response)")
}
.addDisposableTo(disposeBag)
Variableってのも存在していて、これがまた便利
公式Docはここ
Variableは値が変わればストリームがonNextされ、他で購読している場所も更新される。
(始めは僕も理解ができなかった。)
例として、true_buttonとfalse_buttonの二つを用意して、trueをタップしたらactivityIndicator
をアニメーションさせ、
falseをタップしたらアニメーションを終了させてみる
let loading: Varible<Bool> = Variable(false) //型パラメーターでどんな値もストリーム化できる
true_button.rx_tap
.map { _ in true }
.bindTo(loading)
.addDisposableTo(disposeBag)
false_button.rx_tap
.map { _ in true }
.bindTo(loading)
.addDisposableTo(disposeBag)
loading
.bindTo(indicator.rx_animating)
.addDisposableTo(disposeBag)
これで、ボタンを押してloadingの値がtrueかfalseに更新された時、下のところでloadingを購読しているところも更新される。
なのでactivityIndicatorをリアルタイムでアニメーションさせる事ができる。
値が変わった時に他の関係ある値も更新したい時(UIなど)はVariableを使うとすごく便利!
Variableにしておくことで値が変わった時に自動的にそのVaribleを購読している場所の値も更新される!
まとめ
ざっと、覚えている例で初めてRxSwiftを触った最初の1-2ヶ月でよく使ったオペレーターや理解が難しかったけど、まず覚えると便利!なものをまとめてみました!
自分自身もっと川をひく勉強をしないとです(> <)