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
contenteditable と日本語入力に向き合う
colorful12
0
120
Webの地図
yosuke_furukawa
PRO
6
5.1k
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.8k
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2.8k
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
470
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
910
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
520
Rでドレミ/Do-Re-Mi_with_R
florets1
0
120
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
680
Heart of Swift Concurrency
koher
0
1.2k
setup-vp GitLab対応の裏側
naokihaba
0
150
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
140
Featured
See All Featured
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
440
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
Facilitating Awesome Meetings
lara
57
7.2k
Building AI with AI
inesmontani
PRO
1
1.3k
The Cost Of JavaScript in 2023
addyosmani
55
10k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
The untapped power of vector embeddings
frankvandijk
2
1.9k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
710
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