- id, passを入力する。
- id, pass未記入ならば、"ID and Password are not entered." と表示
- passが未記入ならば、"ID has not been entered."と表示。
- idが未記入ならば、"Password has not been entered."と表示。
- id,passが記入済みならば、"OK"と表示。
- Swift5
- アーキテクチャはMVVM
- 作り方
- StoryboardでViewを作成し、ViewControllerに宣言する。
- Modelを定義する。エラーとバリデーションを定義。
- ここでは、ビジネスロジックがバリデーションになるためこれをモデルとする。
- Viewのロジックを担うViewModelを作成。
- Viewから流れてきたid,passの文字列をテキスト�を受け取る。
- そのテキスト内容に連動したメッセージ(エラー含む)、そのメッセージの色を流す。Viewはそれを受けて表示する。
- ViewModelとのデータバインディングを行う。
- enum ModelError: Errorの定義
- invalidId
- invalidPassword
- invalidIdAndPassword
- enumにvar errorText: Stringを定義
- .invalidIdAndPassword "IDとPasswordが未入力です。"
- .invalidId "IDが未入力です。"
- .invalidPassword "Passwordが未入力です。"
- protocol ModelProtocolでvalidateを定義
- そのprotocolに批准したModelクラスを作成
- validate関数はid,passのOptional Stringのタプルを引数。戻り値は、Observable
- 渡ってきたタプルをswitchで判定。Optional.none, Optional.some。
- そのswitch文にて定義したenum ModelError: Error に振り分ける。
- 空文字の場合も判定する。 case (let idText.isEmpty, passwordText.isEmpty)
- どちらも空文字でなければ、Observable.just(())
- 渡ってきたタプルをswitchで判定。Optional.none, Optional.some。
- idTextField: UITextField, passwordTextField: UITextField, validationLabel: UILabelをOutletで宣言する。
- idTextField, passwordTextFieldからViewModelへのデータバインディング&ViewModelのインスタンス化
- viewModelはidTextField, passwordTextFieldのtextをObservable化したもの、他にModelから初期化する。
- viewModelからのデータバインディング
- viewModelのvalidtionTextをvalidationLabelのtextにバインド
- viewModelのloadLabelColorをvalidationDescriptionのUIColorにバインドする
- validationText: Observable, loadLabelColor: Observableをメンバ変数を持つ。
- この2つのObseravableのメンバ変数がViewとデータバインディングされる。
- initでidTextObservable: Observable<String?>,passwordTextObservable: Observable<String?>,model: ModelProtocol
- からvalidationText: Observable, loadLabelColor: Observableのストリームに流す。
- (ViewControllerがViewModelクラスのインスタンスを保持している。)
- combineLatestでidTextObservable, passwordTextObservableをひとまとめにする。
- 渡ってきた2つのObservable<String?>をmodel.validateでバリデーションをかける。
- materializeを使うと、ObservableをObservable<Eventに変換することができます。
- https://egg-is-world.com/2018/08/04/rxswift-materialize-dematealize/
- そのバリデーションした結果をもとにvalidationTextとloadLabelColorの変数に入れたいので、share()を記述。
- validationText
- .next: .just("OK"), .error(let error): just(エラーの内容), .error, .completed: .empty()
- loadLabelColor
- next: .green, .error: .red, .completed: .empty()