ios - 没有在 RxSwift 上使用 RxMoya 获得 Completed 事件

标签 ios swift uitableview rx-swift moya

以下代码有效:

    let provider = RxMoyaProvider<MyAPI>( stubClosure: MoyaProvider.delayedStub(3))

    provider
        .request(.studentSearch(query: ""))
        .retry(3)
        .observeOn(MainScheduler.instance)
        .asObservable()
        .mapJSON()
        .map { respJSON in
            guard let studentsJsonArray = JSON(respJSON)["students"].array else {
                throw APIError.wrongJSONParsing
            }
            return studentsJsonArray.map {
                guard let students = Student.fromJSON($0) else {
                    fatalError("Invalid Student Object")
                }
                return students
                } as [Student]
        }
        .subscribe(onNext: {
          print($0)
        }, onCompleted: {
          print($0) // This one is being called.
        })
        .disposed(by: rx.disposeBag)

上面的代码中调用了 onCompleted 方法,但下面的代码中没有调用。

我正在尝试使用刷新触发器来完成此操作,例如 UITableView 中用于刷新内容的触发器。我想在开始时加载内容,因此我在 ViewModel 的以下代码中使用 startWith(())

let results: Driver<[Student]>
var refreshTrigger = PublishSubject<Void>()
results = refreshTrigger
        .startWith(())
        .do(onNext: {
            execute.value = true
        })
        .flatMapLatest {
            provider
                .request(.studentSearch(query: ""))
                .retry(3)
                .observeOn(MainScheduler.instance)
                .asObservable()
        }
        .mapJSON()
        .map { respJSON in
            guard let studentsJsonArray = JSON(respJSON)["students"].array else {
                throw APIError.wrongJSONParsing
            }
            return studentsJsonArray.map {
                guard let students = Student.fromJSON($0) else {
                    fatalError("Invalid Student Object")
                }
                return students
            }
        }
        .do(onNext: {
            items.value = $0
            execute.value = false
            noResults.value = items.value.isEmpty
        }, onCompleted: {
            print($0)
        })
        .asDriver(onErrorJustReturn: [])

在 Controller 中,我在 viewdidload 中调用以下内容。

viewModel
        .results
        .asObservable()
        .map { StudentGroup(header: "Follower", items: $0) }
        .subscribe(onNext: {
            print($0)
        }, onCompleted: {
            print($0) // This is not being called.
        })
        .disposed(by: rx.disposeBag)

这里 onCompleted 没有被调用。我不知道为什么?请帮帮我。

最佳答案

除非其输入(在您的情况下为 PublishSubject)完成,否则 flatMapLatest 不会发送 onCompleted 事件。 Moya 请求可以发送自己的 onCompleted 事件,但是当 flatMapLatest 合并结果时,这些事件会被过滤掉。 换句话说,从 PublishSubject 到数据源的长期订阅未完成,也不应该完成。 (已编辑) (否则您将在第一次加载后失去刷新功能。)

我从 RxSwift Slack channel 获得了 Zsolt Varadi 的帮助。

解决办法在这里

results = refreshTrigger
        .startWith(())
        .do(onNext: {
            execute.value = true
        })
        .flatMapLatest {
            provider
                .request(.studentSearch(query: ""))
                .retry(3)
                .observeOn(MainScheduler.instance)
                .asObservable()
                .mapJSON()
                .map { respJSON in
                    guard let studentsJsonArray = JSON(respJSON)["students"].array else {
                        throw APIError.wrongJSONParsing
                    }
                    return studentsJsonArray.map {
                        guard let students = Student.fromJSON($0) else {
                            fatalError("Invalid Student Object")
                        }
                        return students
                        } as [Student]
                }
                .map { StudentGroup(header: "Follower", items: $0) }
                .toArray()
                .catchErrorJustReturn([])
                .do(onNext: {
                    studentGroups.value = $0
                    execute.value = false
                    guard let isEmpty = studentGroups.value.first?.items.isEmpty else {
                        return
                    }
                    noResults.value = isEmpty
                })
        }
        .asDriver(onErrorJustReturn: [])

关于ios - 没有在 RxSwift 上使用 RxMoya 获得 Completed 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46422066/

相关文章:

ios - 如何在 CABasicAnimation 之后使 UI 对象响应

ios - UIStoryboard Controller 类作为基类

swift - 扩展中的重载函数会产生错误

ios - 在 Swift、iOS 中将表格 View 转换为多页 PDF 的最佳方法之一

iOS:TableView 中的多个部分不起作用

ios - PhoneGap : Added Animated gif to index. 适用于测试设备,但不适用于应用商店下载

javascript - iPhone 的点击和鼠标移动?

ios - 表格 View 中的可能错误

ios - 从iOS应用上传视频到youtube--Youtube API

ios - 如果我在 UIViewController 中有两个 UITableView,我如何检测哪个 tableview 正在滚动?