一个Combine Demo。 Combine是苹果发布的响应式框架,iOS13一起发布的,所以最低iOS13才能使用。
做了一个简单登录界面的异步处理演示。
页面逻辑说明:
-
获取验证码按钮是否启用(isEnabled)跟手机号输入框值是否有效有关。输入11位长度字符串获取验证码按钮isEnabled变为true。
-
登录按钮是否启用(isEnabled)跟三个控件状态或值相关联,分别是:手机号输入框内容、验证码输入框内容以及同意隐私政策开关。三个控件同时满足校验才能改登录按钮isEnabled位true。
代码部分
创建三个用@Published修饰的变量,用于接受控件内容
Swift
@Published var phone: String? = ""
@Published var verifyCode: String? = ""
@Published var isAgree: Bool = false
@IBAction func phoneChanged(_ sender: UITextField) { phone = sender.text }
@IBAction func verifyCodeChanged(_ sender: UITextField) { verifyCode = sender.text }
@IBAction func agreeChanged(_ sender: UISwitch) { isAgree = sender.isOn }
创建校验手机号发布者,输出值为布尔类型
Swift
// 校验手机号的发布者
var phoneValid: AnyPublisher<Bool, Never> {
$phone
.map { $0?.count == 11 ? true : false }
.eraseToAnyPublisher()
}
创建校验验证码发布者
Swift
// 校验验证码的发布者
var verifyCodeValid: AnyPublisher<Bool, Never> {
$verifyCode
.map { code in
guard // 验证码校验逻辑(实际情况按照需求自定义)
let code = code, // 值不能为nil
code.count == 4, // 长度为4
let _ = Int(code) // 能转为Int
else { return false } // 以上三种全部满足返回true,否则返回false
return true
}
.eraseToAnyPublisher() // 抹去类型转为AnyPublisher
}
合并三个发布者 - CombineLatest
Swift
// 融合三个发布者
Publishers.CombineLatest3(phoneValid, verifyCodeValid, $isAgree)
.map { $0 && $1 && $2 } // 筛选逻辑
.receive(on: RunLoop.main) // 在主线程接受
.assign(to: \.isEnabled, on: toLogin) // 结果分配
.store(in: &subscriptions) // 返回值Cancellable对象储存在全局容器中