最近は、以前挫折したRxSwiftをもう一度勉強中な感じです。
RxSwiftやMVVM周りでわかったことは今後別の記事にあげていこうと思っています。
今日は小ネタな感じで、少しつまづいたことを書いていこうと思います。
textField.rx.text.bindはエラーと言われてしまう
UITextFieldのObservableをViewModel側のObserverにbindしようとした時、 なぜかできませんでした。
※bindしようとしている対象はObserverです。(ViewModel側で以下のように宣言して公開しています)
// viewModel import RxSwift import RxCocoa import Foundation class viewModel { private let titleEditStream = PublishSubject<String>() var titleEdit: AnyObserver<String> { return titleEditStream.asObserver } //以下省略 }
というように、textFieldに入力されたら(イベントが流れ始めたら)、viewmodel側にイベントストリームを流したいと考えていたのですが、 上記の画像のようにエラーになってしまいました。
理由
どうしてエラーが発生するのかというのは、単純でした。 流れてくるイベント(この場合だと入力された文字列)はStringではなく、String?だったからです。
これはRxを使用していなくても標準のもので、UITextField.textの型はString?です。
宣言しているObserverの方の型(ジェネリクスの部分)はStringのため、String?→Stringに変える必要があります。
どうするか
RxにはorEmptyというpropertyがあります。 それを使用することで、String?→Stringに変換してくれます。
orEmptyがどのように実装されているのかはこんな感じでした。
※RxCocoa/ControlProperty.swift
コードの中のコメントにも書いているように、String? → Stringに変換してくれています。 実際は、mapで変換していましたね。
let values: Observable<String> = original._values.map{ $0 ?? "" }
画像のソースコードについて
※valuesはObservableです。(returnでObservable
※valuesSinkはObserverです。(AnyObserver, returnでAnyObserver
ということで、orEmptyを使用することでbind(to: ~)を使用してもエラーが表示されなくなりました。