Soumettre la recherche
Mettre en ligne
RxSwiftをバインディングツールとして使ってみる
•
0 j'aime
•
958 vues
Hironytic
Suivre
tokushima.app #7で発表したスライド
Lire moins
Lire la suite
Logiciels
Signaler
Partager
Signaler
Partager
1 sur 17
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
Algorithm 速いアルゴリズムを書くための基礎
Algorithm 速いアルゴリズムを書くための基礎
Kenji Otsuka
メタプログラミング C#
メタプログラミング C#
Fujio Kojima
.NET MVP によるドキドキ・ライブコーディング! 小島の分
.NET MVP によるドキドキ・ライブコーディング! 小島の分
Fujio Kojima
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
ノンプログラマーでも明日から使えるJavaScript簡単プログラム 先生:柳井 政和
schoowebcampus
Backbone.js
Backbone.js
daisuke shimizu
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
Fujio Kojima
探検!SwiftyJSON
探検!SwiftyJSON
Yuka Ezura
JS 6th edition reading circle part 2
JS 6th edition reading circle part 2
Teloo
Contenu connexe
En vedette
RxSwift コードリーディングの勘所@社内RxSwift勉強会
RxSwift コードリーディングの勘所@社内RxSwift勉強会
Yuki Takahashi
RxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけ
Hironytic
今日こそ理解するHot変換
今日こそ理解するHot変換
Yuki Takahashi
RxSwift x APIKit
RxSwift x APIKit
Kosuke Usami
MVVM & RxSwift
MVVM & RxSwift
Thai Son Dang
iOS開発 本当にあった怖い話
iOS開発 本当にあった怖い話
Kazuhiro Sakamoto
マルチスレッドRxSwift @ 社内RxSwift勉強会
マルチスレッドRxSwift @ 社内RxSwift勉強会
Yuki Takahashi
RxSwift x Realm
RxSwift x Realm
Kosuke Usami
What is reactive programming?
What is reactive programming?
Kenji Tanaka
Java → Kotlin 変換 そのあとに。
Java → Kotlin 変換 そのあとに。
健一 辰濱
コンポーネント単位で考えるWeb制作
コンポーネント単位で考えるWeb制作
祐磨 堀
Apakah saudara sudah tahu politikituapa
Apakah saudara sudah tahu politikituapa
henry jaya teddy
Quitters, climbers, campers
Quitters, climbers, campers
henry jaya teddy
Allah isa almasih, muslim, bani israel sama
Allah isa almasih, muslim, bani israel sama
henry jaya teddy
Apakah saudara sudah tahu sn dan ss
Apakah saudara sudah tahu sn dan ss
henry jaya teddy
Продвижение в инстаграм на свадебном рынке
Продвижение в инстаграм на свадебном рынке
Daria Manelova
Medical Revelation Of India
Medical Revelation Of India
kiran karanjkar
Heart transformation
Heart transformation
henry jaya teddy
Apakah saudara sudah tahu ump jakarta 3,1 juta rupiah
Apakah saudara sudah tahu ump jakarta 3,1 juta rupiah
henry jaya teddy
Apakah saudara sudah tahu kelakukanpenulisblogislam
Apakah saudara sudah tahu kelakukanpenulisblogislam
henry jaya teddy
En vedette
(20)
RxSwift コードリーディングの勘所@社内RxSwift勉強会
RxSwift コードリーディングの勘所@社内RxSwift勉強会
RxSwiftのデータバインディングだけ
RxSwiftのデータバインディングだけ
今日こそ理解するHot変換
今日こそ理解するHot変換
RxSwift x APIKit
RxSwift x APIKit
MVVM & RxSwift
MVVM & RxSwift
iOS開発 本当にあった怖い話
iOS開発 本当にあった怖い話
マルチスレッドRxSwift @ 社内RxSwift勉強会
マルチスレッドRxSwift @ 社内RxSwift勉強会
RxSwift x Realm
RxSwift x Realm
What is reactive programming?
What is reactive programming?
Java → Kotlin 変換 そのあとに。
Java → Kotlin 変換 そのあとに。
コンポーネント単位で考えるWeb制作
コンポーネント単位で考えるWeb制作
Apakah saudara sudah tahu politikituapa
Apakah saudara sudah tahu politikituapa
Quitters, climbers, campers
Quitters, climbers, campers
Allah isa almasih, muslim, bani israel sama
Allah isa almasih, muslim, bani israel sama
Apakah saudara sudah tahu sn dan ss
Apakah saudara sudah tahu sn dan ss
Продвижение в инстаграм на свадебном рынке
Продвижение в инстаграм на свадебном рынке
Medical Revelation Of India
Medical Revelation Of India
Heart transformation
Heart transformation
Apakah saudara sudah tahu ump jakarta 3,1 juta rupiah
Apakah saudara sudah tahu ump jakarta 3,1 juta rupiah
Apakah saudara sudah tahu kelakukanpenulisblogislam
Apakah saudara sudah tahu kelakukanpenulisblogislam
Similaire à RxSwiftをバインディングツールとして使ってみる
たのしい関数型
たのしい関数型
Shinichi Kozake
Sansan様 登壇資料
Sansan様 登壇資料
Daisuke Nagata
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
Yuta Okamoto
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
mganeko
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
Nobuaki Oshiro
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Yoshifumi Kawai
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposium
Tomohiro Kumagai
C++0x in programming competition
C++0x in programming competition
yak1ex
プログラミング言語Scala
プログラミング言語Scala
TanUkkii
Swiftyを試す
Swiftyを試す
幸雄 村上
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
nagachika t
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz
Tomoharu ASAMI
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
y_taka_23
ApexトリガのBest Practiceを目指して
ApexトリガのBest Practiceを目指して
Takahiro Yonei
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
聡 中川
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
Nobuaki Oshiro
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
Akira Takahashi
Visualforce + jQuery
Visualforce + jQuery
Salesforce Developers Japan
Swift - Result<t>型で結果を返すのは邪道か,王道か
Swift - Result<t>型で結果を返すのは邪道か,王道か
Yuichi Yoshida
Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
Similaire à RxSwiftをバインディングツールとして使ってみる
(20)
たのしい関数型
たのしい関数型
Sansan様 登壇資料
Sansan様 登壇資料
Why Reactive Matters #ScalaMatsuri
Why Reactive Matters #ScalaMatsuri
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Swift 2.0 大域関数の行方から #swift2symposium
Swift 2.0 大域関数の行方から #swift2symposium
C++0x in programming competition
C++0x in programming competition
プログラミング言語Scala
プログラミング言語Scala
Swiftyを試す
Swiftyを試す
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
実務者のためのかんたんScalaz
実務者のためのかんたんScalaz
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
ApexトリガのBest Practiceを目指して
ApexトリガのBest Practiceを目指して
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
Visualforce + jQuery
Visualforce + jQuery
Swift - Result<t>型で結果を返すのは邪道か,王道か
Swift - Result<t>型で結果を返すのは邪道か,王道か
Clojure programming-chapter-2
Clojure programming-chapter-2
Plus de Hironytic
DroidKaigi 2018報告会(公式アプリへのコントリビュート)
DroidKaigi 2018報告会(公式アプリへのコントリビュート)
Hironytic
DroidKaigi 2018報告会(はじめてのKotlinハンズオン)
DroidKaigi 2018報告会(はじめてのKotlinハンズオン)
Hironytic
DroidKaigi 2018報告会(会場の風景)
DroidKaigi 2018報告会(会場の風景)
Hironytic
Firebaseの新しいデータベース
Firebaseの新しいデータベース
Hironytic
CocoaPodsのはなし
CocoaPodsのはなし
Hironytic
Heroku+MongoLabでダミーサーバー
Heroku+MongoLabでダミーサーバー
Hironytic
Plus de Hironytic
(6)
DroidKaigi 2018報告会(公式アプリへのコントリビュート)
DroidKaigi 2018報告会(公式アプリへのコントリビュート)
DroidKaigi 2018報告会(はじめてのKotlinハンズオン)
DroidKaigi 2018報告会(はじめてのKotlinハンズオン)
DroidKaigi 2018報告会(会場の風景)
DroidKaigi 2018報告会(会場の風景)
Firebaseの新しいデータベース
Firebaseの新しいデータベース
CocoaPodsのはなし
CocoaPodsのはなし
Heroku+MongoLabでダミーサーバー
Heroku+MongoLabでダミーサーバー
RxSwiftをバインディングツールとして使ってみる
1.
RxSwiftを バインディングツール として使ってみる 2016/07/24 tokushima.app #7 @hironytic
2.
自己紹介 • 一宮 浩教 •
徳島市内で働く iOS/Android/Windows(ストアアプリ) エンジニア • https://twitter.com/hironytic • https://github.com/hironytic
3.
RxSwift • https://github.com/ReactiveX/RxSwift • http://reactivex.io/ •
RxJavaとかRxJSとか、アレの仲間
4.
足し算アプリ • 数値入力欄 ×2 •
計算ボタン(=) • 数値入力欄を両方埋めると 計算ボタンが有効 • 計算ボタンを押すと入力さ れた2つの数値を足し算し た結果を表示
5.
RxSwiftっぽく var disposeBag =
DisposeBag() override func viewDidLoad() { super.viewDidLoad() let numbers = Observable.combineLatest(number1Field.rx_text, number2Field.rx_text) { ($0, $1) } numbers .map { (number1, number2) in return !number1.isEmpty && !number2.isEmpty } .bindTo(calcButton.rx_enabled) .addDisposableTo(disposeBag) calcButton.rx_tap .withLatestFrom(numbers) .map { (number1, number2) in let n1 = Int(number1) ?? 0 let n2 = Int(number2) ?? 0 return String(n1 + n2) } .startWith("") .bindTo(answerLabel.rx_text) .addDisposableTo(disposeBag) } !今回の話では 忘れてください ViewController
6.
RxSwiftを使わないなら override func viewDidLoad()
{ super.viewDidLoad() number1Field.text = "" number2Field.text = "" answerLabel.text = "" calcButton.enabled = false } @IBAction private func calc(sender: AnyObject) { let n1 = Int(number1Field.text ?? "") ?? 0 let n2 = Int(number2Field.text ?? "") ?? 0 answerLabel.text = String(n1 + n2) } @IBAction func number1Changed(sender: AnyObject) { updateCalcState() } @IBAction func number2Changed(sender: AnyObject) { updateCalcState() } private func updateCalcState() { calcButton.enabled = !(number1Field.text?.isEmpty ?? true) && !(number2Field.text?.isEmpty ?? true) } ViewController 計算ボタンの タップ 数値 入力時
7.
今回のやり方 var disposeBag =
DisposeBag() let viewModel = ViewModel() override func viewDidLoad() { super.viewDidLoad() viewModel.number1Text .bindTo(number1Field.rx_text) .addDisposableTo(disposeBag) viewModel.number2Text .bindTo(number2Field.rx_text) .addDisposableTo(disposeBag) viewModel.calcEnabled .bindTo(calcButton.rx_enabled) .addDisposableTo(disposeBag) viewModel.answerText .bindTo(answerLabel.rx_text) .addDisposableTo(disposeBag) number1Field.rx_text .bindTo(viewModel.number1ChangedAction) .addDisposableTo(disposeBag) number2Field.rx_text .bindTo(viewModel.number2ChangedAction) .addDisposableTo(disposeBag) calcButton.rx_tap .bindTo(viewModel.calcAction) .addDisposableTo(disposeBag) } ViewControllerViewModel に分割 ViewModelの 出力を バインド ViewModelの 入力へ バインド
8.
今回のやり方 let number1Text: Observable<String> let
number2Text: Observable<String> let calcEnabled: Observable<Bool> let answerText: Observable<String> let number1ChangedAction: AnyObserver<String> let number2ChangedAction: AnyObserver<String> let calcAction: AnyObserver<Void> private let _number1Text = Variable<String>("") private let _number2Text = Variable<String>("") private let _calcEnabled = Variable<Bool>(false) private let _answerText = Variable<String>("") private let _calcAction = ActionObserver<Void>() private let _number1ChangedAction = ActionObserver<String>() private let _number2ChangedAction = ActionObserver<String>() init() { number1Text = _number1Text.asObservable() number2Text = _number2Text.asObservable() answerText = _answerText.asObservable() calcEnabled = _calcEnabled.asObservable() number1ChangedAction = _number1ChangedAction.asObserver() number2ChangedAction = _number2ChangedAction.asObserver() calcAction = _calcAction.asObserver() _calcAction.handler = { [weak self] in self?.calc() } _number1ChangedAction.handler = { [weak self] in self?.number1Changed($0) } _number2ChangedAction.handler = { [weak self] in self?.number2Changed($0) } } ViewModel 外に公開した 入出力 状態の保持
9.
今回のやり方 private func calc()
{ let n1 = Int(_number1Text.value) ?? 0 let n2 = Int(_number2Text.value) ?? 0 _answerText.value = String(n1 + n2) } private func number1Changed(value: String) { _number1Text.value = value updateCalcState() } private func number2Changed(value: String) { _number2Text.value = value updateCalcState() } private func updateCalcState() { _calcEnabled.value = !_number1Text.value.isEmpty && !_number2Text.value.isEmpty } ViewModel
10.
🐣 なにがうれしいの?
11.
MVVM View ViewModel Model 外観 プラットフォ ームの都合 UIの状態 UIのための ロジック ビジネス ロジック 呼び出し 通知 バイン ディング WPFなら XAML+コード ビハインド RxSwift
12.
ViewModelのテスト • UIロジックのテスト • UIテストって面倒じゃないですか? -
デザインの変更に弱いとか - Accessibility Identifierとか • ViewModelのテストでUIロジックはテストできる
13.
ViewModelのテスト func testCalc() { let
disposeBag = DisposeBag() let viewModel = ViewModel() let answerObserver = FulfillObserver( expectationWithDescription("empty before calculation")) { $0 == "" } viewModel.answerText .bindTo(answerObserver) .addDisposableTo(disposeBag) waitForExpectationsWithTimeout(1.0, handler: nil) answerObserver.reset( expectationWithDescription("30 after calculation")) { $0 == "30" } viewModel.number1ChangedAction.onNext("10") viewModel.number2ChangedAction.onNext("20") viewModel.calcAction.onNext() waitForExpectationsWithTimeout(1.0, handler: nil) } Test
14.
まとめ 🚀バインディングだけのために、 RxSwiftを使うという選択肢も ありじゃないの? 📃ソースコード https://github.com/hironytic/RxSwiftBindingExample
15.
補足 • Rxのoperatorを使った一般的なやり方をdisってい るわけではありません!!🙇 - 個人的にはObservableの川は結構好きです •
Rxのoperatorを使ってもViewModelは作れます - RxSwift本家のサンプル - 今回のViewModelを公開した入出力はそのままで、 Rxのoperatorを使うようにもできます
16.
ViewModel改 let number1Text: Observable<String> let
number2Text: Observable<String> let calcEnabled: Observable<Bool> let answerText: Observable<String> let number1ChangedAction: AnyObserver<String> let number2ChangedAction: AnyObserver<String> let calcAction: AnyObserver<Void> private let _number1Text = BehaviorSubject<String>(value: "") private let _number2Text = BehaviorSubject<String>(value: "") private let _calcAction = PublishSubject<Void>() init() { number1Text = _number1Text.asObservable() number2Text = _number2Text.asObservable() number1ChangedAction = _number1Text.asObserver() number2ChangedAction = _number2Text.asObserver() calcAction = _calcAction.asObserver() let numbers = Observable.combineLatest(number1Text, number2Text) { ($0, $1) } calcEnabled = numbers .map { (number1, number2) in return !number1.isEmpty && !number2.isEmpty } answerText = _calcAction .withLatestFrom(numbers) .map { (number1, number2) in let n1 = Int(number1) ?? 0 let n2 = Int(number2) ?? 0 return String(n1 + n2) } .startWith("") } ViewModel 外に公開した 入出力
17.
おしまい ありがとうございました
Télécharger maintenant