我想从 what、how、why 几个方面,简单的写一下如何用 RXSwift 写响应式代码。
what is RxSwift?
在计算机中,响应式编程是一种面向数据流和变化传播的异步编程范式。
举个例子:
1 | let a = b + c |
在命令式编程中,这个表达式是计算 b 和 c 的和 a。假如之后 b 和 c 变化了,a 也不会变化。
而在响应式编程里,a 会随着 b 和 c 的变化而变化,不用再次执行这块代码求出一个值,再赋值给 a。
响应式编程可以简化交互式用户界面的开发,比如将视图与数据流绑定,数据流有新的值的时候,视图则会自动响应变化。
ReactiveX 是一组提供异步的数据流的 api,在 ReactiveX 的眼中,一切都可以当作数据流,我们可以用它来轻松的开始响应式编程。
而 RxSwift 就是 ReactiveX 的 Swift 实现。
how to use RxSwift?
怎么用好 RxSwift 呢?使用 RxSwift 的关键,是如何转变思维,写出响应式代码。
举个例子,在登录页面,会对账号和密码的输入框做校验,账号限制为 11 位字符,密码限制为 6 到 20 个字符,只有在账号和密码都有效的情况下,登录按钮才可点击。
命令式编程
在命令式编程下的典型思路是这样的 1
21. 实现账号 TextField 以及密码 TextField 的 delegate 的字符串变化的方法,获取到他们的字符串
2. 根据字符串的变化,设置登录按钮的enable状态
具体实现我就不写了,相信大家已经写了很多遍了
响应式编程
在响应式编程下的典型思路是这样1
2
3
41. 获取账号和密码的字符流 userNameInputStream、passWordInputStream
2. 将账号流转换为账号是否有效的流 userNameValidStream、passWordValidStream
3. 将 userNameValidStream、passWordValidStream 两个流合并为判断账号和密码是否有效的流 loginValidStream
4. 将 loginValidStream 与登录按钮绑定
流程如图
show you the code1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30weak var passWordField: UITextField!
weak var userNameField: UITextField!
weak var loginButton: UIButton!
let bag = DisposeBag()
private func bindView(){
//生成流
let passWordInput = self.passWordField.rx.text
let userNameInput = self.userNameField.rx.text
//转换流
let passWordValid = passWordInput.map { (passWord) -> Bool in
if let passWord = passWord{
return passWord.count > 6 && passWord.count < 20
}
return false
}
let userNameValid = userNameInput.map { (userName) -> Bool in
if let userName = userName {
return userName.count == 11
}
return false
}
//合并流
let loginValid = Observable<Bool>.combineLatest(userNameValid, passWordValid) { (userName, passWord) -> Bool in
return userName && passWord
}
//绑定
loginValid.bind(to: self.loginButton.rx.isEnabled).disposed(by: bag)
}
可以看出这些代码主要在做的事情,就是流的生成、转换、合并,以及最后与 UI 的绑定。代码看起来也很直观,业务逻辑一目了然,减少了潜在性的错误。
why RxSwift?
RxSwift 是一个利器,而且它的扩展库 RxCocoa 将 UIKit 里的大部分 UI 控件做了 Reactive 化,可以很方便的对控件进行数据绑定,以及监控控件的变化。使用 RxSwift 我们可以省去命令式编程下的很多胶水代码,通过流的转换合并,轻易的写出复杂的逻辑。
响应式编程的难点一个是学习曲线比较陡峭,一个是思维转换比较困难,踏过这两个坎之后,就会发现一个新世界了。