蜀道之难,难于上青天

0%

响应式编程 与 RXSwift(一)

我想从 whathowwhy 几个方面,简单的写一下如何用 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
2
1. 实现账号 TextField 以及密码 TextField 的 delegate 的字符串变化的方法,获取到他们的字符串
2. 根据字符串的变化,设置登录按钮的enable状态

具体实现我就不写了,相信大家已经写了很多遍了

响应式编程

在响应式编程下的典型思路是这样

1
2
3
4
1. 获取账号和密码的字符流 userNameInputStream、passWordInputStream
2. 将账号流转换为账号是否有效的流 userNameValidStream、passWordValidStream
3. 将 userNameValidStream、passWordValidStream 两个流合并为判断账号和密码是否有效的流 loginValidStream
4. 将 loginValidStream 与登录按钮绑定

流程如图
登录按钮流

show you the code

1
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
30
@IBOutlet weak var passWordField: UITextField! 
@IBOutlet weak var userNameField: UITextField!
@IBOutlet 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 我们可以省去命令式编程下的很多胶水代码,通过流的转换合并,轻易的写出复杂的逻辑。
响应式编程的难点一个是学习曲线比较陡峭,一个是思维转换比较困难,踏过这两个坎之后,就会发现一个新世界了。