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.7k
Apple Pay対応のやりかた
bricklife
1
25k
iOS版グローバル対応の罠と技
bricklife
8
24k
Other Decks in Programming
See All in Programming
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
170
Formの複雑さに立ち向かう
bmthd
1
720
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
5
3.8k
Linux && Docker 研修/Linux && Docker training
forrep
23
4.5k
AHC041解説
terryu16
0
590
Conform を推す - Advocating for Conform
mizoguchicoji
3
680
CI改善もDatadogとともに
taumu
0
110
ARA Ansible for the teams
kksat
0
150
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
200
How mixi2 Uses TiDB for SNS Scalability and Performance
kanmo
29
11k
Writing documentation can be fun with plugin system
okuramasafumi
0
120
2024年のWebフロントエンドのふりかえりと2025年
sakito
1
230
Featured
See All Featured
A designer walks into a library…
pauljervisheath
205
24k
Being A Developer After 40
akosma
89
590k
Fireside Chat
paigeccino
34
3.2k
A Tale of Four Properties
chriscoyier
158
23k
Designing for humans not robots
tammielis
250
25k
Designing Experiences People Love
moore
139
23k
Rails Girls Zürich Keynote
gr2m
94
13k
Mobile First: as difficult as doing things right
swwweet
223
9.3k
Automating Front-end Workflow
addyosmani
1367
200k
[RailsConf 2023] Rails as a piece of cake
palkan
53
5.2k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
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
⼀緒に川遊びしま しょう!