Reactive Cocoa 5和ReactiveSwift网络请求处理

我正在尝试使用ReactiveSwift和RAC5来确定是否可以根据我的需要实现网络请求处理。

在主题从RACSignal迁移到ReactiveSwift或RAC5下我被告知可以使用SignalProducer完成,但深入研究它并没有给我预期的结果

所以,我想要:
1.每次文本更改textField发送请求(按关键字搜索)。
2.用户关闭当前ViewController后,应自动取消当前请求
3.一旦更改关键字,就有能力取消请求

这就是我所拥有的

self.textField.reactive.continuousTextValues.skipNil().filter({ (value) -> Bool in return value.characters.count > 0 }).observeValues { [unowned self] (value) in self.fetchSignalDisposable?.dispose() self.fetchSignal = self.producerFor(keyword: value).on(started: { print("started") }, failed: { (error) in print("error") }, completed: { print("completed") }, value: { [unowned self] (items) in print("value") self.items.append(contentsOf: items) self.tableView.reloadData() }) self.fetchSignalDisposable = self.fetchSignal!.start() } 

这是生产者初始化器

 return SignalProducer { (observer, disposable) in let task: URLSessionDataTask? = NetworkClient.fetchRequestWith(uri: "test", parameters: ["keyword" : keyword], success: { response in observer.send(value: response) observer.sendCompleted() }, failure: { error in observer.send(error: error) observer.sendCompleted() }) disposable += { task?.cancel() } } 

笔记:
1.有时候我想要有成功和错误调用的“处理程序块”,因此隐藏加载指示符之类的东西可以在该块下完成。

这里几个问题/问题:
1.一旦我关闭VC(解除动作),再次调用observeValue处理程序。 它可以通过添加.skipRepeats()来修复,但我想这只是一种解决方法而不是一个确切的解决方案。 如果我关闭VC,我希望不再让这个观察者活跃起来
2.在发生错误的情况下未调用completed块,即使我在调用send(error: error)后立即手动调用它send(error: error)
3.如果请求仍在加载并关闭VC,则不会自动处理 ,这对我来说很奇怪。 我认为一旦viewController失去对signalProducer的引用,就会自动调用dispose块。 甚至在VC的deinit方法中调用self.fetchSignalDisposable?.dispose()也不会取消请求。 它仍然完成请求并调用value处理程序,导致Bad Access错误崩溃

我的个人需求是:
1.在成功和失败的请求案例之后都会有一些“两个”块
2.关闭VC后,必须删除textFields文本值的所有观察者,并且不再处于活动状态
3.关闭VC时必须取消网络请求

PS:当然,感谢大家阅读这篇文章并花时间帮助我!

ReactiveSwift自述文件中的“制作网络请求”示例就是这种类型的一个很好的例子。 而不是在文本字段信号上使用observeValues ,通常你会使用.flatMap(.latest)直接将它连接到你的SignalProducer上(注意我没有检查过这段代码,但希望它可以解决这个问题):

 self.textField.reactive.continuousTextValues .skipNil() .filter { (value) -> Bool in return value.characters.count > 0 } .flatMap(.latest) { [unowned self] value in return self.producerFor(keyword: value) // Handling the error here prevents errors from terminating // the outer signal. Now a request can fail while allowing // subsequent requests to continue. .flatMapError { error in print("Network error occurred: \(error)") return SignalProducer.empty } } .observe(on: UIScheduler()) .observe { [unowned self] event in switch event { case let .value(items): print("value") self.items.append(contentsOf: items) self.tableView.reloadData() case let .failed(error): print("error") case .completed, .interrupted: print("completed") } } 

指定.latest会导致先前的网络请求在新的网络请求启动时自动取消,因此无需在全局变量中跟踪当前请求。

至于管理生命周期,如果不了解更广泛的代码结构,很难说最好的是什么。 通常情况下,我会.take(during: self.reactive.lifetime)我的信号中添加.take(during: self.reactive.lifetime)类的东西, .take(during: self.reactive.lifetime)取消分配self时终止订阅,可能就在observe调用之前。

错误事件终止信号。 发生错误后无需发送已完成的事件,观察者无论如何都不会看到它。 基本上,complete表示信号成功终止,而错误表明信号终止失败。