Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReactiveCocoaのゆるい紹介とメルカリでの活用事例

 ReactiveCocoaのゆるい紹介とメルカリでの活用事例

Retty Tech Cafe第3回「スタートアップ×iOS開発」で発表した資料に加筆+修正をしたものです

https://atnd.org/events/67600

Shinichiro Oba

August 11, 2015
Tweet

More Decks by Shinichiro Oba

Other Decks in Programming

Transcript

  1. ReactiveCocoaのゆるい紹介と  
    メルカリでの活⽤用事例例
    株式会社メルカリ  
    iOSエンジニア  
    ⼤大庭慎⼀一郎郎

    View full-size slide

  2. ⾃自⼰己紹介
    ⼤大庭  慎⼀一郎郎  (ooba  /  bricklife)  
    株式会社メルカリ  
    2013年年4⽉月⼊入社  
    「メルカリ」iOS版を開発

    View full-size slide

  3. メルカリとは?
    いわゆる「フリマアプリ」  
    2013年年7⽉月  JP版リリース  
    2014年年8⽉月  US版リリース

    View full-size slide

  4. はじめに
    間違っていても怒怒らないで…!  
    ツッコミは⼤大歓迎です!  
    先⼈人たちによる偉⼤大なドキュメント
    からの引⽤用多め

    View full-size slide

  5. ReactiveCocoaの  
    ゆるい紹介

    View full-size slide

  6. ReactiveCocoaとは
    "ReactiveCocoa  (RAC)  is  a  Cocoa  
    framework  inspired  by  Functional  
    Reactive  Programming.  It  provides  
    APIs  for  composing  and  transforming  
    streams  of  values  over  time.”  
    https://github.com/ReactiveCocoa/ReactiveCocoa

    View full-size slide

  7. Functional  Reactive  
    Programming  (FRP)  とは?

    View full-size slide

  8. FRPとは
    「⾮非同期データストリームを⽤用いた
    プログラミング」などと説明される
    ことが多い

    View full-size slide

  9. よくわかんない\(^o^)/  

    View full-size slide

  10. よくわからないので
    ReactiveCocoa  (RAC)  が提供する
    ものから追っていきたいと思います

    View full-size slide

  11. RACが提供するもの
    1. ストリームを⽣生成する⽅方法  
    2. ストリームを加⼯工する⽅方法  
    3. ストリームを監視する⽅方法  
    +便便利利なマクロ

    View full-size slide

  12. ようするにRACは  
    ストリームを作ったり使ったり
    するライブラリ

    View full-size slide

  13. これがストリームだ!
    完了了
    エラー
    データ
    時間
    どちらかの発⽣生によって  
    ストリームが終わる
    開始 or

    View full-size slide

  14. ストリームの⽣生成
    RACはCocoaフレームワーク上の様々な
    ものをストリームに変えられる  
    例例:⽂文字列列、配列列、KVO、UIイベント、
    ネットワーク通信、デリゲートメソッド
    呼び出し、etc.

    View full-size slide

  15. RACが提供するカテゴリ

    View full-size slide

  16. 配列列のストリーム化

    [0,  1,  2,  3]

    View full-size slide

  17. タップのストリーム化
    タップ ダブルタップ タップ

    View full-size slide

  18. テキスト⼊入⼒力力のストリーム化
    " "#$
    "# "#
    A B C Delete

    View full-size slide

  19. ネットワーク通信のストリーム化
    ϦΫΤετ ड৴த ड৴׬ྃ
    த਎͸
    Ϩεϙϯε

    View full-size slide

  20. IUUQTHJTUHJUIVCDPNTUBMU[FFCDBCDG

    View full-size slide

  21. ストリームの加⼯工
    ストリーム上のデータに対して  filter  した
    り  map  したり  merge  したり  zip  したり  
    reduce  したりできる  
    オペレータと呼ばれる  
    ここが関数型、すなわちFunctional!

    View full-size slide

  22. filter
    IUUQOFJMQBNFSBDNBSCMFTpMUFS

    View full-size slide

  23. map
    IUUQOFJMQBNFSBDNBSCMFTNBQ

    View full-size slide

  24. merge
    IUUQOFJMQBNFSBDNBSCMFTNFSHF

    View full-size slide

  25. zip
    IUUQOFJMQBNFSBDNBSCMFT[JQ

    View full-size slide

  26. reduce
    IUUQOFJMQBNFSBDNBSCMFTSFEVDF

    View full-size slide

  27. 例例:ダブルタップのストリーム
    IUUQTHJTUHJUIVCDPNTUBMU[FFCDBCDG

    View full-size slide

  28. どんな加⼯工ができるか
    「RAC  Marbles」やその元の「RxMarbles」を⾒見見る
    とオペレータの種類とその効果がインタラクティブに
    わかるのでオススメ  
    http://neilpa.me/rac-‐‑‒marbles/  
    http://rxmarbles.com/

    View full-size slide

  29. ストリームの監視
    購読  (Subscribe)  という  
    ストリームに流流れてくるデータを順次処理理  
    配列列に戻す、UIへの表⽰示、プロパティの更更新、
    画⾯面遷移、etc.

    View full-size slide

  30. すべてを使ったコードの例例
    [[[self.textField rac_textSignal] filter:^BOOL(NSString *value) {
    return value.length > 0;
    }] subscribeNext:^(NSString *value) {
    NSLog(@“%@", value);
    }];
    -‐‑‒rac_̲textSignal ⼊入⼒力力⽂文字列列からストリームを⽣生成
    -‐‑‒filter: ストリームをfilterして空⽂文字列列が
    含まれないように加⼯工
    -‐‑‒subscribeNext: ストリームを購読してログ出⼒力力

    View full-size slide

  31. 便便利利なマクロ
    たったこれだけで  text  プロパティの変更更を
    ラベルに⾃自動反映できる!
    RAC(self.label, text)
    = RACObserve(self, text);

    View full-size slide

  32. ストリームを使ってできること
    リスト処理理  
    ⾮非同期イベント処理理  
    データバインディング  
    Promise  
    MVVM,  etc.

    View full-size slide

  33. なにがうれしいか
    いろんな⾮非同期処理理を  
    「ストリームをどう扱うか」  
    という視点から「宣⾔言的」に記述できる

    View full-size slide

  34. メルカリでの活⽤用事例例

    View full-size slide

  35. RAC導⼊入の歴史
    2014/8に  pod  ʻ‘ReactiveCocoaʼ’  
    最初に使ったのはUIAlertViewのRACサポート  
    徐々に適⽤用箇所を広げる  
    現在iOSエンジニア4⼈人全員がRACを使うように

    View full-size slide

  36. 読み込んだ記事
    The  introduction  to  Reactive  Programming  
    you've  been  missing  
    https://gist.github.com/staltz/868e7e9bc2a7b8c1f754  
    【翻訳】あなたが求めていたリアクティブプログラミ
    ング⼊入⾨門  
    http://ninjinkun.hatenablog.com/entry/introrxja

    View full-size slide

  37. 読み込んだ本
    「Functional  Reactive  Programming  on  iOS」  
    https://leanpub.com/iosfrp/
    当時の表紙

    View full-size slide

  38. RACでやっていること
    リスト処理理  
    ⾮非同期イベント処理理  
    データバインディング  
    Promise  
    MVVM,  etc.

    View full-size slide

  39. RACを使っている画⾯面
    住所編集画⾯面  
    住所⼀一覧画⾯面  
    銀⾏行行情報編集画⾯面  
    検索索条件選択画⾯面  
    通知設定画⾯面  
    ⽀支払い⽅方法選択画⾯面  
    商品⼀一覧画⾯面  
    購⼊入画⾯面  
    検索索コーチマーク画⾯面  
    検索索サジェスト画⾯面

    View full-size slide

  40. 実際の画⾯面は  
    メルカリをダウンロードして  
    ⾒見見てください!!!
    IUUQTJUVOFTBQQMFDPNKQBQQJE

    View full-size slide

  41. データバインディングの例例
    銀⾏行行情報編集画⾯面  
    プロパティの変更更をテキストフィールドに⾃自動反映  
    検索索サジェスト画⾯面  
    テキストフィールドの変更更をプロパティに⾃自動反映
    RAC(self.accountNumberTextField, text)
    = RACObserve(self.viewModel, accountNumber);
    RAC(self, inputText) = textField.rac_textSignal;

    View full-size slide

  42. Promiseの例例
    購⼊入画⾯面  
    タイムアウトを設けた失敗してもよい⾮非同期処理理と
    購⼊入APIの完了了を両⽅方待つ
    RACSignal *timeoutSignal = [[RACSignal merge:@[
    _btDataSignal,
    [RACSignal interval:kBTDataTimeout
    onScheduler:[RACScheduler mainThreadScheduler]],
    ]] take:1];
    [RACSignal combineLatest:@[_buyAPISignal, timeoutSignal]] subscribeNext:^(RACTuple *tuple) {
    //...
    } error:^(NSError *error) {
    //...
    }];

    View full-size slide

  43. MVVMを導⼊入した画⾯面
    住所編集画⾯面  
    住所⼀一覧画⾯面  
    銀⾏行行情報編集画⾯面  
    検索索条件選択画⾯面  
    通知設定画⾯面  
    ⽀支払い⽅方法選択画⾯面  
    商品⼀一覧画⾯面  
    購⼊入画⾯面  
    検索索コーチマーク画⾯面  
    検索索サジェスト画⾯面

    View full-size slide

  44. MVVMとは
    Model  View  ViewModelというMVCの派⽣生パターン  
    https://ja.wikipedia.org/wiki/Model_̲View_̲ViewModel  
    ViewModelはViewを描画するための状態の保持と、
    Viewから受け取った⼊入⼒力力を適切切な形に変換してModel
    に伝達する役⽬目  
    ViewModelはテストできる!

    View full-size slide

  45. 応⽤用例例:インクリメンタルサーチ
    検索索サジェスト画⾯面  
    以下とほぼ同じ実装をしている  
    http://qiita.com/ikesyo/items/e699eefe1d0985158420
    個⼈人的にFRPが本領領発揮するケースの1つだと思う
    [[[[[textField.rac_textSignal filter:^BOOL(NSString *text) {
    return text.length > 0;
    }] throttle:0.5] map:^(NSString *text) {
    return [[APIClient sharedClient] fetchSearchResultWithQuery:text];
    }] switchToLatest] subscribeNext:^(id JSON) {
    NSLog(@"Search result: %@", JSON);
    }];

    View full-size slide

  46. RAC導⼊入時の注意

    View full-size slide

  47. 導⼊入コストが⾼高い
    概念念の理理解に時間がかかる  
    メルカリでは独学と知⾒見見のシェアでなんとかした  
    まずはデータバインディングかPromiseからはじめ
    るといいかも  
    ⼤大量量のオペレータを理理解する必要がある  
    関数型⾔言語をやっていればなんとかなるか…?

    View full-size slide

  48. 循環参照しやすい
    便便利利マクロ@strongifyと@weakifyを駆使  
    「Implicit  retain  of  ʻ‘selfʼ’  within  blocks」をYesに  
    Instrumentsでメモリの利利⽤用状況をチェック  
    AllocateのMark  Generationが便便利利

    View full-size slide

  49. 最初は⼤大変だけど  
    慣れると楽になってきますよ!

    View full-size slide

  50. ありがとうございました!
    スライド内のURL以外に参考にしたURL  
    http://havelog.ayumusato.com/develop/javascript/e657-‐‑‒
    reactive_̲programming_̲in_̲javascript.html  
    http://qiita.com/amay077/items/5e7cedb069a5a6ae0ae7  
    http://yohshiy.blog.fc2.com/blog-‐‑‒entry-‐‑‒215.html  
    http://www.slideshare.net/taketin/mvvm-‐‑‒40956834

    View full-size slide