Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RxSwift 3.3.0: Observable のフレンズが増えました!!
Search
tondol
April 17, 2017
Programming
2.8k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RxSwift 3.3.0: Observable のフレンズが増えました!!
Single すごーい!!
tondol
April 17, 2017
More Decks by tondol
See All by tondol
ちいさく始めるレイヤードアーキテクチャ
tondol
7
2.1k
Amazon Cloud Driveのご紹介
tondol
0
580
自家製オタクソリューションの紹介
tondol
1
570
ドはDockerのド
tondol
1
2.9k
Other Decks in Programming
See All in Programming
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
540
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
580
The Rails Doctrine Decade
koic
2
500
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
Simple Storage Service(S3) is not simple
iwatsukayura
0
190
Verilogで学ぶCPU自作入門.pdf
uyuki234
8
4k
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
140
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
130
パーソナライズPodcastを作った話
repunit11
0
120
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
370
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
440
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
620
The Language of Interfaces
destraynor
162
27k
Designing for humans not robots
tammielis
254
26k
How to Ace a Technical Interview
jacobian
280
24k
VelocityConf: Rendering Performance Case Studies
addyosmani
331
25k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
540
How Software Deployment tools have changed in the past 20 years
geshan
2
35k
Making Projects Easy
brettharned
120
6.8k
Transcript
RxSwift 3.3.0: Observableのフレンズが 増えました!! @tondol / HOSAKA Tomoyuki from Kyobashi.swift
2017.4.17 AKIBA.swift 1周年
誰? • @tondol / 保坂 智之 (HOSAKA Tomoyuki) • kidsly
(保育⼠x保護者コミュニケーションサービス) • 前回AKIBA.swiftさんとコラボしたときの記事 • https://tech.recruit-mp.co.jp/event/kyoakiswift/
a • a
RxSwiftの紹介
RxSwift? • 使っていますか? • try! Swift にも Rx のトークがありましたね •
何が嬉しいの? • ⾮同期処理もUIイベントも、 あらゆるものが Observable で表現される • Observable 間のフローを宣⾔すれば、 あとは⾃動的にUIが反応し始める世界観(最⾼) • レイヤー間の糊付けにも • @nonchalant0303 の資料を参照のこと
Observable? • N個の値が⾮同期に流れるストリーム • 誤解を恐れず⾔うなら「強いPromise」 • Promise • ひとつの⾮同期な値 に対する
正常時とエラー時の処理を記述・表現するもの • then, catch によるチェイン • Observable • 複数の⾮同期な値 に対する 正常時とエラー時の処理を記述・表現するもの • map などのオペレータによるチェイン • bind 機構による Observable 同⼠の連携
よくあるValidationのデモ • 仕様 • サインアップにはメルアドとパスワードが必要 • メルアドはそれっぽいバリデーション付ける • パスは8桁以上、確認⽤フィールドも⽤意する •
リアルタイムにエラー表⽰、ボタンの有効・無効化 • それ RxSwift でできるよ!
パスワード UITextField .rx.text 登録ボタン UIButton .rx.isEnabled Observable#bind パス再⼊⼒ UITextField .rx.text
Observable.combineLatest Observable#map 8桁以上 && 再⼊⼒パスと⼀致
よくあるValidationのデモ • 仕様 • サインアップにはメルアドとパスワードが必要 • メルアドはそれっぽいバリデーション付ける • パスは8桁以上、確認⽤フィールドも⽤意する •
リアルタイムにエラー表⽰、ボタンの有効・無効化 • それ RxSwift でできるよ! • すご〜い! • リアルタイムUIに強いフレンズライブラリ なんだね!
以降が本題
よくあるAPIコール • URLSession 等による通信処理を Rx でラップ • APIKit でも Alamofire
でもなんでもいい • Observable.create を使うと簡単にできる private var count = 0 // API コールを Observable による I/F で実装したと思ってください。 fileprivate func fetchWithObservable() -> Observable<[String]> { // 自分で Observable を作るときは Observable.create を使います。 return Observable.create { [unowned self] observer in self.count += 1 observer.onNext(["わーい!", "すごーい!", "¥(self.count)回目"]) observer.onCompleted() return Disposables.create() } }
private var count = 0 // toots は画面外のコードでUIにバインドされていると思ってください。 private let
toots = PublishSubject<[String]>() private let bag = DisposeBag() fileprivate func didTapReloadButton() { // タップする度に新しいトゥートが表示されることを期待しているが・・・ fetchWithObservable() .bind(to: toots) .addDisposableTo(bag) } // API コールを Observable による I/F で実装したと思ってください。 fileprivate func fetchWithObservable() -> Observable<[String]> { // 自分で Observable を作るときは Observable.create を使います。 return Observable.create { [unowned self] observer in self.count += 1 observer.onNext(["わーい!", "すごーい!", "¥(self.count)回目"]) observer.onCompleted() return Disposables.create() } } よくあるAPIコールだが……
2回⽬以降の更新がされない!!
private var count = 0 // toots は画面外のコードでUIにバインドされていると思ってください。 private let
toots = PublishSubject<[String]>() private let bag = DisposeBag() fileprivate func didTapReloadButton() { // タップする度に新しいトゥートが表示されることを期待しているが・・・ fetchWithObservable() .bind(to: toots) .addDisposableTo(bag) } // API コールを Observable による I/F で実装したと思ってください。 fileprivate func fetchWithObservable() -> Observable<[String]> { // 自分で Observable を作るときは Observable.create を使います。 return Observable.create { [unowned self] observer in self.count += 1 observer.onNext(["わーい!", "すごーい!", "¥(self.count)回目"]) observer.onCompleted() return Disposables.create() } } よくあるAPIコール(まちがい) 返り値の Observable を bind すると completed イベントで toots も終了 → 想定と違う挙動に!! すぐ completed になるけど Observable<[String]>
private var count = 0 // toots は画面外のコードでUIにバインドされていると思ってください。 private let
toots = PublishSubject<[String]>() private let bag = DisposeBag() fileprivate func didTapReloadButton() { // これなら completed が toots に影響しないためセーフ fetchWithObservable() .subscribe(onNext: { [unowned self] newToots in self.toots.onNext(newToots) }) .addDisposableTo(bag) } // API コールを Observable による I/F で実装したと思ってください。 fileprivate func fetchWithObservable() -> Observable<[String]> { // 自分で Observable を作るときは Observable.create を使います。 return Observable.create { [unowned self] observer in self.count += 1 observer.onNext(["わーい!", "すごーい!", "¥(self.count)回目"]) observer.onCompleted() return Disposables.create() } } よくあるAPIコール(せいかい) bind ではなく、 subscribe で toots を更新する
completed が影響しないため、 2回⽬以降も想定通り更新される
今回のタイトル: Observableのフレンズが 増えました!!
None
None
Single / Completable / Maybe • RxSwift 3.3.0 の新機能 •
いずれもObservableの仲間=フレンズ • RxJava, RxJS などのRxファミリーではお馴染み • Observable<T> → N個の値のストリーム • Single<T> → 1個の値のストリーム • 型でより強い制約を表現できる • Promiseに近い使い⽅ができる!
よくあるAPIコール(w/ Single) private var count = 0 // toots は画面外のコードでUIにバインドされていると思ってください。
private let toots = PublishSubject<[String]>() private let bag = DisposeBag() fileprivate func didTapReloadButton() { // これなら completed が toots に影響しないためセーフ fetchWithSingle() .subscribe(onSuccess: { [unowned self] newToots in self.toots.onNext(newToots) }) .addDisposableTo(bag) } // こちらは Single で実装したバージョン。 fileprivate func fetchWithSingle() -> Single<[String]> { // Single も Single.create で作ることができます。 return Single.create { [unowned self] observer in self.count += 1 event(.success(["わーい!", "すごーい!", "¥(self.count)回目"])) return Disposables.create() } } 2. Singleに対しては そもそもbindが提供されていないので、 ⾃然とこうなる 1. Singleを返すようにする
Single / Completable / Maybe • Single • .success(T), .error(Error)
• Completable • .completed, .error(Error) • 雑感: Single<Void> でも事⾜りるのでは • Maybe • .success(T), .completed, .error(Error) • 雑感: 値が0個でもcompleteできるのがポイント • ObservableType#asSingle でも作れる
おわりに • すぐ complete する Observable は、 Observable よりも Single
で表現しよう!! • 個⼈的に遭遇した便利な例を共有しました • 他に便利な場⾯があったら教えてください〜 • 「Rx、まだよくわからないんですが・・・」 • 最初は Promise/Future の代替くらいのノリで • Welcome to ようこそ RxSwift パーク • 興味のある⽅は懇親会でお話しましょう!! • ReactiveSwift の話も聞きたいっす
Appendix • 参考⽂献 • ReactiveX/RxSwift CHANGELOG • https://github.com/ReactiveX/RxSwift/blob/master/ CHANGELOG.md •
RxSwift 3.3.0で追加された3つのUnit • http://qiita.com/monoqlo/items/7bcec98432389b3 b8909 • デモコードのリポジトリ • https://github.com/tondol/AKIBASwift- ObservableFriends