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
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
400
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
460
速習iPhone Duo対応
yuukiw00w
1
450
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
150
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
230
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
460
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
2.9k
AHC070解法紹介
eijirou
0
120
一人だけ、Kiroが静止する日
hideg
0
110
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
1k
Building an Out-of-Order CPU
latte72
1
780
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
470
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
First, design no harm
axbom
PRO
2
1.3k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
690
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Facilitating Awesome Meetings
lara
57
7.1k
Building AI with AI
inesmontani
PRO
1
1.2k
Docker and Python
trallard
47
4.2k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
590
Discover your Explorer Soul
emna__ayadi
2
1.3k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.6k
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