最新的ReactiveCocoa使用网上能找到的资料特别少,为了给接入swift版reactivecocoa的开发者提供便利,我就讲常用场景下的使用, 就拿注册页面来举例,如有异议和问题欢迎指正交流,言归正传,注册页面一般由一些信息需要用户填写,一般我们用UITableView展示,UITableView的使用我就不提了,上代码
fileprivate let verifyCode = MutableProperty<String>("")
....
func verifyCodeCell(at indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "verify_cell", for: indexPath) as! ABVerifyCodeCell
self.verifyButton = cell.verifyCodeButton
// import Then
return cell.with {
$0.textField.reactive.text <~ self.verifyCode.producer.take(until: cell.reactive.prepareForReuse)
$0.textField.reactive
.continuousTextValues
.take(until: cell.reactive.prepareForReuse)
.map { $0 ?? "" }
.observeValues{ [weak self] in
self?.verifyCode.value = String($0.characters.prefix(6))
}
$0.verifyCodeButton.reactive
.controlEvents(.touchUpInside)
.take(until: cell.reactive.prepareForReuse)
.observeValues { [weak self] _ in
self?.getVerifyCode()
}
}
}
由于cell重用问题,textField内容绑定必须调用以下方法来实现重用时解除之前的绑定
$0.textField.reactive.text <~ self.verifyCode.producer.take(until: cell.reactive.prepareForReuse)
以下代码用来限制输入的字符数,开发者也可以再次限制输入的内容,如手机号码校验等
.observeValues{ [weak self] in
self?.verifyCode.value = String($0.characters.prefix(6))
}
一切尽在代码中,文笔太差就不多废话了
在需要多个请求都返回时才处理后续流程这种情况下,如果不使用ReactiveCocoa,需要保留很多状态
使用ReactiveCocoa就简单多了,贴代码
func requestPropertyValue() -> SignalProducer<PropertyValueModel, RequestError> {
return SignalProducer { (observer, lifeTime) in
let params = ["module" : PropertyValueService.ModuleProperty.prod.rawValue]
let requestTask = PropertyValueService()
.request(
params,
transform: {
var result = [String : String]()
$0["data"].arrayValue.forEach {
result[$0["mappingName"].stringValue] = $0["propName"].stringValue
}
return PropertyValueModel(propMap: result)
},
completionHandler: {
if $0.isSuccess {
observer.send(value: $0.value!)
observer.sendCompleted()
} else {
observer.send(error: $0.error as! RequestError)
}
})
lifeTime += AnyDisposable {
requestTask?.cancel()
}
}
}
func requestProductCustomerNo() -> SignalProducer<String, NoError> {
return SignalProducer { observer, _ in
ProductNoService()
.request(
nil,
transform: { $0["prodCustomNo"].stringValue },
completionHandler: {
observer.send(value: $0.isSuccess ? $0.value! : "")
observer.sendCompleted()
})
}
}
func requestCustomerNoAndPropertyValue() {
let customerNoProducer = requestProductCustomerNo().promoteError(RequestError.self)
let propProducer = requestPropertyValue()
customerNoProducer
.combineLatest(with: propProducer)
.observe(on: UIScheduler())
.on(starting: { [weak self] _ in
if let strongSelf = self {
strongSelf.showLoadingOnView(strongSelf.view)
}
})
.startWithSignal { signal, _ in
signal.observeResult { [weak self] result in
if let strongSelf = self {
strongSelf.hideLoadingForView(strongSelf.view)
if let value = result.value {
strongSelf.customNo.value = value.0
strongSelf.generatedProdNo = value.0
strongSelf.tableView.reloadData()
}
}
}
}
}
combineLatest函数使多个信号都响应时才通知,不需要保留任何临时状态就优雅的解决了这种问题