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.2k
Swift 2.0でRxSwift、ReactKit、ReactiveCocoaを使ってみた
bricklife
10
4.8k
ReactiveCocoaのゆるい紹介とメルカリでの活用事例
bricklife
3
3.6k
Apple Pay対応のやりかた
bricklife
1
25k
iOS版グローバル対応の罠と技
bricklife
8
24k
Other Decks in Programming
See All in Programming
gopls を改造したら開発生産性が高まった
satorunooshie
8
240
飲食業界向けマルチプロダクトを実現させる開発体制とリアルな現状
hiroya0601
1
390
Vue3の一歩踏み込んだパフォーマンスチューニング2024
hal_spidernight
3
3.1k
破壊せよ!データ破壊駆動で考えるドメインモデリング / data-destroy-driven
minodriven
16
4.1k
CSC305 Lecture 13
javiergs
PRO
0
130
ECSのサービス間通信 4つの方法を比較する 〜Canary,Blue/Greenも添えて〜
tkikuc
11
2.3k
Modern Angular: Renovation for Your Applications
manfredsteyer
PRO
0
210
Realtime API 入門
riofujimon
0
110
CSC509 Lecture 08
javiergs
PRO
0
110
macOS でできる リアルタイム動画像処理
biacco42
7
1.9k
Snowflake x dbtで作るセキュアでアジャイルなデータ基盤
tsoshiro
2
430
のびしろを広げる巻き込まれ力:偶然を活かすキャリアの作り方/oso2024
takahashiikki
1
410
Featured
See All Featured
Designing the Hi-DPI Web
ddemaree
280
34k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
32
1.8k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
107
49k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Building Your Own Lightsaber
phodgson
102
6k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
6.9k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
363
19k
The Language of Interfaces
destraynor
154
24k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
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
⼀緒に川遊びしま しょう!