ReactiveCocoa的开发指北

3 篇文章 0 订阅
2 篇文章 0 订阅

最新的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函数使多个信号都响应时才通知,不需要保留任何临时状态就优雅的解决了这种问题

再举个使用场景,对于搜索,假定我们需要针对用户的输入内容显示相关的匹配,这种情况如果用户没输入或删除一个字符就响应对用户来说太不友好了,

浪费网络流量,网络流量就是金钱啊,对服务端也是压力,这种时候就需要对客户端进行限流处理了,一般想到的方法就是用定时器加一堆判断逻辑,

我们知道定时器用不好就会导致内存泄漏,这种情况如果用RAC处理就简单的令人发指,开个玩笑说严重了,引用我在代码中的一段

    searchField?.reactive
        .continuousTextValues
        .throttle(0.8, on: QueueScheduler.main)
        .observeValues({ [unowned self] text in
            self.handleSearchTextChange(self.searchField)
        })

是不是很简单,好了,ReactiveCocoa的常用场景下的使用就讲到这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值