Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
アッテ開発の技術:Swift と RxSwift
Search
Shinichiro Oba
April 19, 2016
Programming
19
17k
アッテ開発の技術:Swift と RxSwift
atte FeS【Go・Swift開発編】での発表資料に加筆・修正をしたものです。
http://mercari.connpass.com/event/29506/
Shinichiro Oba
April 19, 2016
Tweet
Share
More Decks by Shinichiro Oba
See All by Shinichiro Oba
サーバサイドエンジニアと効率よく開発するためにやっていること
bricklife
8
2.1k
RxSwiftのobserveOnとsubscribeOnを理解する
bricklife
20
7.4k
Swift 2.0でRxSwift、ReactKit、ReactiveCocoaを使ってみた
bricklife
10
5k
ReactiveCocoaのゆるい紹介とメルカリでの活用事例
bricklife
3
3.7k
Apple Pay対応のやりかた
bricklife
1
25k
iOS版グローバル対応の罠と技
bricklife
8
24k
Other Decks in Programming
See All in Programming
業務自動化をJavaとSeleniumとAWS Lambdaで実現した方法
greenflagproject
1
100
つよそうにふるまい、つよい成果を出すのなら、つよいのかもしれない
irof
1
280
Javaに鉄道指向プログラミング (Railway Oriented Pro gramming) のエッセンスを取り入れる/Bringing the Essence of Railway-Oriented Programming to Java
cocet33000
2
540
Bytecode Manipulation 으로 생산성 높이기
bigstark
1
300
Haskell でアルゴリズムを抽象化する / 関数型言語で競技プログラミング
naoya
17
4.3k
Benchmark
sysong
0
140
実践ArchUnit ~実例による検証パターンの紹介~
ogiwarat
2
250
Datadog RUM 本番導入までの道
shinter61
1
260
GoのGenericsによるslice操作との付き合い方
syumai
2
540
C++20 射影変換
faithandbrave
0
440
Cline指示通りに動かない? AI小説エージェントで学ぶ指示書の書き方と自動アップデートの仕組み
kamomeashizawa
1
460
RubyKaigiで得られる10の価値 〜Ruby話を聞くことだけが RubyKaigiじゃない〜
tomohiko9090
0
140
Featured
See All Featured
Building an army of robots
kneath
306
45k
Designing Experiences People Love
moore
142
24k
Site-Speed That Sticks
csswizardry
10
630
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
We Have a Design System, Now What?
morganepeng
52
7.6k
Agile that works and the tools we love
rasmusluckow
329
21k
The Language of Interfaces
destraynor
158
25k
Documentation Writing (for coders)
carmenintech
71
4.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Visualization
eitanlees
146
16k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Typedesign – Prime Four
hannesfritz
42
2.7k
Transcript
アッテ開発の技術 SwiftとRxSwift ⼤庭 慎⼀郎 株式会社メルカリ / 株式会社ソウゾウ 2016/4/18 atte FeS【Go・Swift開発編】
1
⾃⼰紹介 2 ⼤庭 慎⼀郎 ooba / bricklife 株式会社メルカリに2013年4⽉⼊社 現在は株式会社ソウゾウへ出向中 「メルカリ」iOS版の⽴ち上げ
「メルカリ アッテ」iOS版の⽴ち上げ
ϝϧΧϦΞος 3 ʮͳΜͰืूͰ͖Δ ɹҬίϛϡχςΟΞϓϦʯ iOS 8Ҏ߱ରԠ Swift 2.2Ͱઈࢍ։ൃத RxSwiftΛશ໘࠾༻
iOS版開発の歴史 4 できごと メンバー 2015年10⽉ ソウゾウに出向 モック作成開始 ライブラリ&設計検討開始 1 11⽉
RxSwift採⽤決定 本実装開始 合宿 1 12⽉ 幻の初サブミット 1 2016年1⽉ 孤独な⼀⼈開発から脱出 2 2⽉ 紹介制で公開 3 3⽉ 正式オープン 4 4⽉ Go Boldに開発中 4.5
なぜiOS 8以降か
なぜiOS 8以降か 6 2015年10⽉のタイミングでiOS 7のシェ アはわずか iOS 8と7とではSDKが⼤きく違う 実装スピード優先 Carthageが使いたかった
なぜSwiftか 7
なぜSwiftか 8 アッテは新規プロジェクト メルカリiOS版の資産はほぼ使えない ⻑くメンテナンスするコードになる いまSwift採⽤しないでいつ採⽤する? ⼈材募集効果も期待
Swiftでないとできないこと 9 型安全、Optional、enum、etc. APIKitやHimotokiなど⽇本製のイケてる ライブラリを使える • しかしAPIKitはJSON-RPC 2.0と相性が悪かったので泣 く泣く不採⽤ •
同じ思想でJSONRPCKitというのを⾃作した
JSONRPCKit 10 struct Like: RequestType { typealias Response = LikeResult
let offerId: Int64 var method: String { return "LikeService.Like" } var params: AnyObject? { return ["offer_id": NSNumber(longLong: offerId)] } } { id: “1”, jsonrpc: “2.0", method: “LikeService.Like", params: { “offer_id”: 123456; } }
API側の実装 11 type LikeParams struct { OfferId int64 `json:"offer_id"` }
なぜRxSwiftか
その前に
なぜリアクティブ プログラミングか
なぜリアクティブプログラミングか 15 メルカリiOS版では、Objective-Cでリア クティブプログラミングを実現する ReactiveCocoaをヘビーに使っていた もうリアクティブプログラミングなしには プログラムが組めない!
リアクティブプロ グラミングとは
リアクティブプログラミングとは 17 変なこと⾔うとマサカリが⾶んで来るので 説明割愛
リアクティブプログラミングのメリット 18 様々な同期処理や⾮同期処理を 「ストリームをどう扱うか」 という視点から「統⼀的」に かつ「宣⾔的」に記述できる
リアクティブプログラミングが提供するもの 19 1. ストリームを⽣成する⽅法 2. ストリームを加⼯する⽅法 3. ストリームを監視する⽅法
これがストリームだ! 20 どちらかの発⽣によって ストリームが終わる 完了 エラー データ 時間 開始 or
↑この図を「マーブル図」という
ストリームの⽣成 21 ⽂字列、配列、KVO、UIイベント、ネット ワーク通信、デリゲートメソッド呼び出し、 など、なんでもストリームにできる
配列のストリーム化 22 [0, 1, 2, 3]
タップのストリーム化 23 タップ ダブルタップ タップ
テキスト⼊⼒のストリーム化 24 " "#$ "# "# A B C Delete
ネットワーク通信のストリーム化 25 ϦΫΤετ ड৴த ड৴ྃ த Ϩεϙϯε
26 https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
ストリームの加⼯ 27 ストリーム上のデータに対して filter したり map したり merge したり zip
し たり reduce したりできる オペレータと呼ばれる combineLatest や buffer など、時間 概念があるからこそのオペレータもある
filter 28 http://rxmarbles.com/#filter
map 29 http://rxmarbles.com/#map
merge 30 http://rxmarbles.com/#merge
zip 31 http://rxmarbles.com/#zip
reduce 32 http://rxmarbles.com/#reduce
combineLatest 33 http://rxmarbles.com/#combineLatest
buffer 34 http://reactivex.io/documentation/operators/ buffer.html
オペレータを組み合わせた例:ダブルタップ 35 https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
ストリームを使ってできること 36 リスト処理 ⾮同期イベント処理 データバインディング Promise MVVM, etc.
例:テキストフィールドの変更をラベルに⾃動反映 37 textField.rx_text .map { "ʮ\($0)ʯ" } .bindTo(label.rx_text) .addDisposableTo(disposeBag)
例:条件を満たすまでボタンを押せないようにする 38 let textValidation = textField.rx_text .map { !$0.isEmpty }
Observable.combineLatest( textValidation, loading.asObservable()) { text, loading in return text && !loading } .bindTo(submitButton.rx_enabled) .addDisposableTo(disposeBag)
例:インクリメンタルサーチ 39 textField.rx_text .debounce(0.5, scheduler: MainScheduler.instance) .distinctUntilChanged() .map { query
-> Observable<[Item]> in if query.isEmpty { return Observable.just([]) } let request = GetItemsRequest(query: query) return API.responseFrom(request) } .switchLatest() .subscribeNext { [weak self] items in print("next: \(items.count)") self?.items = items self?.tableView.reloadData() } .addDisposableTo(disposeBag)
アッテの実例:画像アップロード後の投稿 40 画像のアップロードと投稿は別API 画像アップロードAPIで画像をアップロー ドするとメディアIDが発⾏される 投稿APIにはメディアIDの配列を渡す
すべての画像をアップロード後の新規投稿 41 combineLatest() ը૾̍ ը૾̎ ը૾̏ ը૾̐
⼀部の画像を再アップロード後の編集投稿 42 combineLatest() ը૾̍ ը૾̎ ը૾̏ ը૾̐
アッテの実例:新規投稿・編集投稿のコード 43 class Photo { var image: UIImage var mediaId:
String? } var request = createUpdateRequest() photos .map { photo -> Observable<String> in if let mediaId = photo.mediaId { return Observable.just(mediaId) } return ImageUploader.uploadImage(photo.image) } .combineLatest { $0 } .map { mediaIds -> Observable<UpdateOfferResult> in request.mediaIds = mediaIds return APIClient.sharedClient.responseFrom(request) } .switchLatest() .subscribe( // ߘAPIͷ݁ՌΛॲཧ ) .addDisposableTo(disposeBag)
Swiftにおける リアクティブプログラ ミング
Swiftにおけるリアクティブプログラミング 45 2015年10⽉時点での選択肢 • ReactiveCocoa • RxSwift • ReactKit
検討中の発表 46 https://speakerdeck.com/bricklife/swift-2-dot-0derxswift- reactkit-reactivecocoawoshi-tutemita
なぜRxSwiftか
RxSwiftのメリット その1 48 RxSwiftとはMicrosoftが2011年にリリース したReactive ExtensionsのSwift版 どの⾔語でもほぼ同じ仕様なので、約5年分 の資産がある RxSwiftは正式にReactiveXへ取り込まれた 開発やコミュニティが活発
RxSwiftのメリット その2 49 他⾔語でRxをしていた⼈は取り組みやすい 今後他⾔語でRxをやるときに経験が活かせ る AndroidではRxJavaがデファクトスタンダー ドなので設計が共有できる?
ReactiveCocoaとReactKitの評価 50 ReactiveCocoaは2015年の時点ではまだα 版で、Readme.mdに書かれているサンプ ルすらコンパイルできない状況… ReactKitは機能的に不⾜を感じた
vs ReactiveCocoa現⾏版 51 いまはReactiveCocoaもかなり成熟 特徴 • Cold ObservableとHot Observableを明確にクラスで分 けている(SignalとSignalProducer)
• エラーに型がある • コードがきれいらしい(伝聞) どこかでちゃんと使ってみたい
RxSwiftのデメリット
RxSwiftのデメリット 53 RxSwift固有のデメリットはいまのところ あまり感じない 強いて⾔えばReactiveCocoaの特徴の反対 • Cold ObservableとHot Observableを混合 •
エラーに型がない
リアクティブプログラミングのデメリット 54 学習コストが⾼い 設計に⼤きく影響(特にMVVM) ライブラリが巨⼤ もし開発が⽌まったらどうする? 頼りきっているとプログラミング能⼒が衰える?
チームへの浸透
有益な資料 56 【翻訳】あなたが求めていたリアクティブプ ログラミング⼊⾨ http://ninjinkun.hatenablog.com/entry/introrxja RxMarbles http://rxmarbles.com 公式ドキュメント(以下は有志の⽇本語版) https://github.com/tid-kijyun/RxSwift/wiki
チームへの浸透 57 前述のドキュメント 既存コード 実装パターンの共有 いい実装にはRPで をつける とにかくRxに触れる機会を増やす
とにかくRxに触れる機会を増やす 58 社内Slackに#tech-rxというRx全般の話をす るチャンネルを設置して、気軽に情報共有や 相談をできるようにしている Reactive Swift Meetupの企画 RxSwift勉強会への参加 ズンドコキヨシ
with RxSwift
⼀緒に川遊びしま しょう!