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.3k
Swift 2.0でRxSwift、ReactKit、ReactiveCocoaを使ってみた
bricklife
10
4.9k
ReactiveCocoaのゆるい紹介とメルカリでの活用事例
bricklife
3
3.6k
Apple Pay対応のやりかた
bricklife
1
25k
iOS版グローバル対応の罠と技
bricklife
8
24k
Other Decks in Programming
See All in Programming
functionalなアプローチで動的要素を排除する
ryopeko
1
210
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
4
1.1k
Запуск 1С:УХ в крупном энтерпрайзе: мечта и реальность ПМа
lamodatech
0
950
Rubyでつくるパケットキャプチャツール
ydah
0
170
ISUCON14感想戦で85万点まで頑張ってみた
ponyo877
1
590
Fibonacci Function Gallery - Part 2
philipschwarz
PRO
0
210
歴史と現在から考えるスケーラブルなソフトウェア開発のプラクティス
i10416
0
300
Swiftコンパイラ超入門+async関数の仕組み
shiz
0
180
責務を分離するための例外設計 - PHPカンファレンス 2024
kajitack
9
2.4k
Beyond ORM
77web
11
1.6k
PicoRubyと暮らす、シェアハウスハック
ryosk7
0
220
React 19でお手軽にCSS-in-JSを自作する
yukukotani
5
570
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
222
9k
The Pragmatic Product Professional
lauravandoore
32
6.4k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Automating Front-end Workflow
addyosmani
1366
200k
The World Runs on Bad Software
bkeepers
PRO
66
11k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Site-Speed That Sticks
csswizardry
3
270
KATA
mclloyd
29
14k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
Typedesign – Prime Four
hannesfritz
40
2.5k
It's Worth the Effort
3n
183
28k
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
⼀緒に川遊びしま しょう!