質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
RxSwift

RxSwiftは、Reactive ExtensionsのSwift向けの実装です。iOS開発に用いられ、リアクティブプログラミングを可能にします。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

4977閲覧

RxCocoa の Driver <-> Signal の変換について

yukin01

総合スコア14

RxSwift

RxSwiftは、Reactive ExtensionsのSwift向けの実装です。iOS開発に用いられ、リアクティブプログラミングを可能にします。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1グッド

0クリップ

投稿2018/08/04 09:29

現在 iOS アプリを MVVM on RxSwift で開発しています。
UILabel に表示するテキストなどには Driver
UIButton のタップイベントなどには Signal を使う方針にしているのですが、
両者は WithLatestFrom で合成できない場合があったりして不便を感じています。

例えば以下のような変換を考えてみたのですが、
意図しない挙動をしないか不安です。(現時点では問題なさそうです)

気をつけるポイントやベストプラクティスがあればご教授いただきたいです。

swift

1signal.asDriver(onErrorJustReturn: hoge) 2signal.flatMap { Driver.just($0) }
kakajika👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

asDriverasSignalがTraitの変換のために用意されているメソッドですから、そちらを使うべきです。

↓のようなコードがうまく動いているのは、たまたまDriverもSignalも実体がSharedSequenceで同じだったからであって、動作が保証されているわけではないと思います。

swift

1signal.flatMap { Driver.just($0) }

両者は WithLatestFrom で合成できない場合があったりして不便を感じています。

どんな場合でしょうか?具体的にコードを貼っていただいた方がよさそうです。

個人的には、DriverやSignalはあくまでView<->ViewModel間の橋渡し的なインターフェースとして使うイメージで、ViewModelの中での合成はいったんObservableに変換してから行うことが多いです。SharedSequenceのままだと使えるオペレーターが限られますし、RxSwiftで開発されているならModel層のインターフェースも大体Observable/Singleなどになっていると思うので、そちらとの連携もしやすくなります。

swift

1// いったんObservableに変換してから合成するサンプルコード 2 3let inputText: Driver<String> 4let buttonDidTap: Signal<Void> 5 6let outputText: Driver<String> = buttonDidTap.asObservable() 7 .withLatestFrom(inputText.asObservable()) 8 .map { "The input value is ($0)" } 9 .asDriver(onErrorJustReturn: "")

投稿2018/08/06 00:53

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukin01

2018/08/12 06:39 編集

ご回答ありがとうございます。 withLatestFrom で両方の値を使う場合に、sharingStrategy が違うとエラーになる(メソッドが用意されていない?)といった例がありました。 ```Swift let hogeEvent: Signal<String> let fugaEvent: Signal<String> let inputtedText: Driver<String> _ = hogeEvent.withLatestFrom(fugaEvent) _ = hogeEvent.withLatestFrom(fugaEvent) { ($0, $1) } _ = hogeEvent.withLatestFrom(inputtedText) _ = hogeEvent.withLatestFrom(inputtedText) { ($0, $1) } // Error ``` 回答していただいた通り、1度全て Observable に変換して処理を行う方法のほか、 ViewModel 内では全て Driver として扱うような方法もあることがわかりました。 Driver で扱うパターンは分かりやすい分キャッシュ増加による懸念点もあるようなので、 プロジェクトを通してどちらかに統一する方針にしようと思います。 Model 部分には元々 Observable を利用していたのもあり、 サンプルコードもあわせてとても分かりやすい解説でした。 ありがとうございました。 参考 https://speakerdeck.com/parakeety/merukariatutefalserxswiftshi-zhuang-gaido https://qiita.com/inamiy/items/d6fa90d0401fa0e83852
kakajika

2018/08/13 06:31

あーなるほど、値の合成もする方のwithLatestFromはSharingStrategyによる制約がかかっているんですね。 > Driver で扱うパターンは分かりやすい分キャッシュ増加による懸念点もあるようなので、 そうですね、自分もDriverは極力使わない派です(というかRxCocoa系のクラスをあまりViewModelから参照したくない)。 View側でViewModelとのバインドを行う処理の中でObservableをDriverに変換するのが一番スッキリするかなと思っていて、今はそうしています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問