前言
這一篇,是一個(gè)仿Github注冊(cè)的表單頁面。官方針對(duì)這個(gè)例子,介紹了用RxSwift實(shí)現(xiàn)MVVM,一個(gè)是使用Driver 序列(針對(duì)UI界面的),另一個(gè)是Observable 序列。所以可以總結(jié)的知識(shí)點(diǎn)如下:
- MVVM的實(shí)現(xiàn)
- Observable序列和Driver序列的區(qū)別
功能說明
還是老樣子,先說明這個(gè)例子做了什么。
其實(shí)就是一個(gè)很經(jīng)典的注冊(cè)表單界面:
- 輸入用戶名,檢驗(yàn)用戶名是否存在
- 輸入密碼,檢驗(yàn)密碼長度
- 輸入確認(rèn)密碼,檢驗(yàn)與上次輸入的密碼是否一致
- 注冊(cè)按鈕,當(dāng)所有輸入內(nèi)容合法時(shí),才能點(diǎn)擊
MVVM的優(yōu)點(diǎn)
以下摘自百度百科
MVVM模式和MVC模式一樣,主要目的是分離視圖(View)和模型(Model),有幾大優(yōu)點(diǎn)
- 低耦合。視圖(View)可以獨(dú)立于Model變化和修改,一個(gè)ViewModel可以綁定到不同的"View"上,當(dāng)View變化的時(shí)候Model可以不變,當(dāng)Model變化的時(shí)候View也可以不變。
- 可重用性。你可以把一些視圖邏輯放在一個(gè)ViewModel里面,讓很多view重用這段視圖邏輯。
- 獨(dú)立開發(fā)。開發(fā)人員可以專注于業(yè)務(wù)邏輯和數(shù)據(jù)的開發(fā)(ViewModel),設(shè)計(jì)人員可以專注于頁面設(shè)計(jì),使用Expression Blend可以很容易設(shè)計(jì)界面并生成xml代碼。
- 可測(cè)試。界面素來是比較難于測(cè)試的,而現(xiàn)在測(cè)試可以針對(duì)ViewModel來寫。
Driver
Driver是RxSwift專門用于處理UI流的,相比Observable,它有以下特點(diǎn):
- 不會(huì)發(fā)出Error
- 在主線程執(zhí)行
- 自動(dòng)添加 shareReplayLatestWhileConnected()
Observable和Driver之間的轉(zhuǎn)換
Observable和Driver的用法基本一致,以下是一個(gè)轉(zhuǎn)化例子
使用Observable:
validateUsername = input.username
.flatMapLatest { username in
return validationService.validateUsername(username)
.observeOn(MainScheduler.instance)
.catchErrorJustReturn(.failed(message: "Error contacting server"))
}
.shareReplay(1)
使用Driver:
validateUsername = input.username
.flatMapLatest { username in
return validationService.validateUsername(username)
.asDriver(onErrorJustReturn: .failed(message: "Error contacting server"))
}
使用 'Driver'的話,會(huì)自動(dòng)地幫我們添加shareReplay(1),并且
.observeOn(MainScheduler.instance)
.catchErrorJustReturn(.Failed(message: "Error contacting server"))
等語句,可以簡(jiǎn)潔的寫為
.asDriver(onErrorJustReturn: .Failed(message: "Error contacting server"))
bindTo和driver
bindTo和driver的作用是一樣的,都是綁定結(jié)果,可以直接這樣理解:
- bindTo用于Observable
- driver用于Driver
使用bindTo,這里的viewModel.validateUsername是Observable類型
viewModel.validateUsername
.bind(to: usernameValidationOutlet.rx.validationResult)
.disposed(by: disposeBag)
使用driver,這里的viewModel.validateUsername是Driver類型
viewModel.validateUsername
.drive(usernameValidationOutlet.rx.validationResult)
.disposed(by: disposeBag)
總結(jié)
具體的代碼就不分析了,其實(shí)就跟之前幾個(gè)例子是一樣的。這個(gè)例子精華在于MVVM的思想,通過ViewModel將視圖和模型綁定在一起,從而達(dá)到解耦的效果。