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
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
560
ドはDockerのド
tondol
1
2.9k
Other Decks in Programming
See All in Programming
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.5k
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.8k
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
3
270
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
260
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
120
typoなんかねぇよ
raspython3
0
660
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
380
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
820
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
150
이 함수, 실패하면 어떻게 되나요? null부터 Rich Errors까지, Kotlin 에러 처리 15년
haeti2
0
130
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
680
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
260
Featured
See All Featured
Raft: Consensus for Rubyists
vanstee
141
7.7k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
260
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
290
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
290
Navigating Weather and Climate Data
rabernat
0
510
WENDY [Excerpt]
tessaabrams
12
39k
Building an army of robots
kneath
306
46k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
510
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
Product Roadmaps are Hard
iamctodd
55
13k
Music & Morning Musume
bryan
47
7.4k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
520
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