#iosdc 2016 A-2 RxSwiftは開発をどう変えたか?

twitter.com

RxSwiftの導入には希望もあれば不安もあると思います。実際、RxSwiftを導入したプロジェクトでの開発では、良いことばかりではなく問題にも直面しました。しかし、プロジェクトに参加してから半年以上たった現在では、やはりRxSwiftを導入して良かったと実感しています。

本トークでは、RxSwiftを利用して実際にどのようなコードを書いてきたのか、実例を交えて紹介します。

iosdc.jp

RxSwiftは開発をどう変えたか?

f:id:niwatako:20160820110034j:plain

メルカリの新規事業チームで働いています。

f:id:niwatako:20160820110040j:plain

f:id:niwatako:20160820110057j:plain

使ったことがある方

かなりいますね

まだ触ったこと無い方どのくらいおられますか

半々ぐらいでしょうか

今日の話の内容は基本的な概念の、アプリのイベントの扱いがどう変わるかのはなしをします。

f:id:niwatako:20160820110147j:plain

ひとことで言うとイベントストリームを抽象化するライブラリです。UITextFieldが編集されたとか。

たとえばテキスト入力はこのように変化します。

f:id:niwatako:20160820110213j:plain

この一連の流れをイベントストリームと呼びます。

イベントストリームをこう表現します。

f:id:niwatako:20160820110236j:plain

たとえばテキストの変化

f:id:niwatako:20160820110250j:plain

このようにiOS SDK の各種イベントをObservableで取得できます。

Observableの個々のイベントの取得の仕方

f:id:niwatako:20160820110324j:plain

f:id:niwatako:20160820110351j:plain

サンプルコードが動いている様子

もう一つBindToというのもあります。

f:id:niwatako:20160820110439j:plain

f:id:niwatako:20160820110503j:plain

上がUITextField、下がUILabel、上から下に反映されます。

f:id:niwatako:20160820110553j:plain

おさらい

f:id:niwatako:20160820110600j:plain

Operator

f:id:niwatako:20160820110625j:plain

実際の開発ではObservableを加工してObserverにバインドすることになる。

f:id:niwatako:20160820110658j:plain

MapやFlatMapはおなじみだと思います。Mapの例を見てみます。

f:id:niwatako:20160820110722j:plain

こうすると入力した文字数がカウントされて表示されます。

f:id:niwatako:20160820110804j:plain

もっと実践的な例。

f:id:niwatako:20160820110837j:plain

Submitすると下に表示される

f:id:niwatako:20160820110842j:plain

オペレータによって二つのTextFieldの最新の値を組み合わせて表示する。

f:id:niwatako:20160820110851j:plain

片方編集する度イベントが発生して更新されてしまうが、buttonでsampleすることで先程のような動きになる。

アプリが作れる気がしてきましたか?

f:id:niwatako:20160820111027j:plain

どんな違いがあるか見てみましょう。

Rxの場合

f:id:niwatako:20160820111045j:plain

ViewDidLoadでバインドするだけで終わる。ViewDidLoadですべての実装が終わるというのは

f:id:niwatako:20160820111105j:plain

あんまりピンときていないですか?

f:id:niwatako:20160820111129j:plain

f:id:niwatako:20160820111133j:plain

f:id:niwatako:20160820111136j:plain

こういうものを組み合わせて水の流れを作るのがRxのやり方。

先ほどの水道のイメージでもう一度見てみましょう

f:id:niwatako:20160820111212j:plain

こうやって組んでおいたら、あとは勝手に流れる。

targetActionのイメージ

f:id:niwatako:20160820111241j:plain

f:id:niwatako:20160820111312j:plain

f:id:niwatako:20160820111414j:plain

テキストのインプットとボタンのタップは従来だと同じイベントとして扱えないので組み合わせにくい。 Rxでは貯めておいたり取りに行ったりすることがない。

f:id:niwatako:20160820111548j:plain

f:id:niwatako:20160820111608j:plain

f:id:niwatako:20160820111622j:plain

f:id:niwatako:20160820111642j:plain

f:id:niwatako:20160820111650j:plain

f:id:niwatako:20160820111700j:plain

実際に取りに行くの面倒なのでランダムな天気を返します

f:id:niwatako:20160820111720j:plain

認可状態と位置情報の二つが変動するが、その二つが変動しても嬉しくないので一つの型にします。本当は中間状態が発生するが、最終的に許可されたかされていないかだけにまとめました。

f:id:niwatako:20160820111815j:plain

f:id:niwatako:20160820111821j:plain

ボタントリガーのハンドリング。IBActionを用意してメソッドを呼ぶ。

f:id:niwatako:20160820111850j:plain

f:id:niwatako:20160820111954j:plain

f:id:niwatako:20160820112041j:plain

ちょっと複雑ですよね

ボタンが押されて

f:id:niwatako:20160820112058j:plain

アラート表示して

f:id:niwatako:20160820112108j:plain

デリゲートが来て

f:id:niwatako:20160820112121j:plain

APIを叩いて

f:id:niwatako:20160820112131j:plain

最後にここ

f:id:niwatako:20160820112140j:plain

Rx の場合

f:id:niwatako:20160820112208j:plain

のつもりだったけど書いてきました

f:id:niwatako:20160820112219j:plain

最新ロケーションの取得をStaticメソッドで用意。

f:id:niwatako:20160820112254j:plain

ロケーションの変化について記述

f:id:niwatako:20160820112316j:plain

ちょっと複雑かもしれないですけどこっちの世界に来たら大したことないですよ

ついにViewControllerに来ました。

f:id:niwatako:20160820112526j:plain

認可されていればAPI、認可されていなければNoneを返す。複数回使うのでShareReplay(1)。

LocationStatusにはdescriptionというステータスがあるのでそれをラベルにバインド。weatherも。

f:id:niwatako:20160820112627j:plain

別々に更新されると気持ち悪いのでweatherでsampleしている。

出来上がり。

何が嬉しいか。処理の流れが終えるということ。どういう順序で何が起きているのかここだけ見れば分かる

f:id:niwatako:20160820112741j:plain

f:id:niwatako:20160820112755j:plain

まとめ

f:id:niwatako:20160820112816j:plain

f:id:niwatako:20160820112827j:plain

デリゲートパターンやtargetActionだと最新の状態をStoredPropertyに貯めないといけない、そういうのがなくなるのも良い。

f:id:niwatako:20160820112912j:plain

本書いてます!!

f:id:niwatako:20160820112922j:plain

今年とは言っていない、冬に出します!よろしくお願いします。

Q&A

コード量、実用的なものを作った時に増えるでしょうか、減るでしょうか

イメージでは総量は増えるかもしれない。Observerを出すまでは多いかもしれないが、Controllerは減るのではないか、大きく増えるわけではなく、なっても1.5倍程度だと思う。

前半でConbineLatestの例があったと思います、Sampleで実行を制限しているが、combineLatestのところは毎回実行される?

f:id:niwatako:20160820113253j:plain

Sampleの下に行くものが制限されるので、おそらく毎回実行されます。チャタリングを抑える仕組みもあるのでそれでうまくいくかもしれないです。

従来型イベントハンドリングと、Rx、全部Rxでやるのか、混在することもあるのでしょうか

全面的に使っていてほとんどObservableだが、なりきっていないところもある。普通のプロパティとしても扱えるしObservableにもなるようなVariableという型?があってそれで間を埋めているような形になっている。

感想

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

twitter.com

まとめ

twitter.com