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
4.9k
ReactiveCocoaのゆるい紹介とメルカリでの活用事例
bricklife
3
3.7k
Apple Pay対応のやりかた
bricklife
1
25k
iOS版グローバル対応の罠と技
bricklife
8
24k
Other Decks in Programming
See All in Programming
アーキテクトと美学 / Architecture and Aesthetics
nrslib
12
3.2k
PsySHから紐解くREPLの仕組み
muno92
PRO
1
540
MCP世界への招待: AIエンジニアが創る次世代エージェント連携の世界
gunta
4
840
Rollupのビルド時間高速化によるプレビュー表示速度改善とバンドラとASTを駆使したプロダクト開発の難しさ
plaidtech
PRO
1
140
The Weight of Data: Rethinking Cloud-Native Systems for the Age of AI
hollycummins
0
230
Boost Your Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
760
SQL Server ベクトル検索
odashinsuke
0
150
安全に倒し切るリリースをするために:15年来レガシーシステムのフルリプレイス挑戦記
sakuraikotone
5
2.6k
Going Structural with Named Tuples
bishabosha
0
190
AHC045_解説
shun_pi
0
360
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
ssssota
1
1.1k
Go1.24 go vetとtestsアナライザ
kuro_kurorrr
2
770
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
268
20k
4 Signs Your Business is Dying
shpigford
183
22k
The Pragmatic Product Professional
lauravandoore
33
6.5k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
135
33k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.7k
Bash Introduction
62gerente
611
210k
Music & Morning Musume
bryan
46
6.4k
Adopting Sorbet at Scale
ufuk
75
9.3k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Why Our Code Smells
bkeepers
PRO
336
57k
How to train your dragon (web standard)
notwaldorf
91
6k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
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
⼀緒に川遊びしま しょう!