ios - 处理 UITableView 绑定(bind)中的连接错误(Moya、RxSwift、RxCocoa)

标签 ios swift rx-swift rx-cocoa rx-binding

我正在使用 RxCoCoa 和 RxSwift 进行 UITableView Biding。 问题是当连接丢失或其他连接错误时,除了服务器错误(我处理了它们)我的应用程序由于下面提到的绑定(bind)错误而崩溃。我的问题是如何处理连接错误?

fileprivate func getNextState() {
        showFullPageState(State.LOADING)
        viewModel.getProductListByID(orderGroup: OrderGroup.SERVICES.rawValue)
                .do(onError: {
                    showStatusError(error: $0)
                    self.showFullPageState(State.CONTENT)
                })
                .filter {
                    $0.products != nil
                }
                .map {
                    $0.products!
                }
                .bind(to: (self.tableView?.rx.items(cellIdentifier: cellIdentifier, cellType: ProductCell.self))!) {
                    (row, element, cell) in
                    self.showFullPageState(State.CONTENT)
                    cell.product = element
                }

                .disposed(by: bag)
        self.tableView?.rx.setDelegate(self).disposed(by: bag)
    }

这是我的ViewModel:

func getProductListByID(orderGroup: String, page: String = "1", limit: String = "1000") -> Observable<ProductRes> {
        return orderRegApiClient.getProductsById(query: getProductQueryDic(stateKey: getNextStateID(product: nextProduct)
                , type: orderGroup, page: page, limit: limit)).map {
            try JSONDecoder().decode(ProductRes.self, from: $0.data)
        }.asObservable()
    }

我将 Moya 用于我的网络层,如下所示:

func getProductsById(query: [String: String]) -> Single<Response> {
        return provider.rx.request(.getProductsById(query))
                .filterSuccessfulStatusCodes()
    }

enter image description here

最佳答案

您没有在任何地方处理错误。我的意思是您承认 do 运算符中的错误,但实际上并没有处理它,只是允许它传递到无法处理错误的 TableView 。

查找catchError 系列运算符以获取解决方案。 .catchErrorJustReturn([]) 可能就是您所需要的。


在评论中,您说:

... I don't want to return empty Array to my table. I want to show the error to customer and customer can retry service

在这种情况下,您应该仅将 .catchError 用于成功链,并为错误设置一个单独的链,如下所示。

fileprivate func getNextState() {
    showFullPageState(State.LOADING)
    let products = viewModel.getProductListByID(orderGroup: OrderGroup.SERVICES.rawValue)
        .share()

    products
        .catchError { _ in Observable.never() }
        .filter { $0.products != nil }
        .map { $0.products! }
        .bind(to: tableView!.rx.items(cellIdentifier: cellIdentifier, cellType: ProductCell.self)) {
            (row, element, cell) in
            self.showFullPageState(State.CONTENT)
            cell.product = element
        }
        .disposed(by: bag)

    products
        .subscribe(onError: { error in
            showStatusError(error: error)
            self.showFullPageState(State.CONTENT)
        })
        .disposed(by: bag)

    self.tableView?.rx.setDelegate(self).disposed(by: bag)
}

按照您设置代码的方式,用户重试该服务的唯一方法是再次调用该函数。如果您想让用户在更具声明性的庄园中重试,您需要将链绑定(bind)到用户可以触发的可观察对象。

关于ios - 处理 UITableView 绑定(bind)中的连接错误(Moya、RxSwift、RxCocoa),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53361150/

相关文章:

ios - RxSwift 只触发一次

ios - 重新实例化 Storyboard导航栏按钮

ios - 执行证书或公钥绑定(bind)的最简单方法

ios - Rx swift : code working only first time

ios - UITableView - 仅在触摸时突出显示单个单元格

ios - 无法识别的选择器发送到 Swift 中的实例?

swift - 尾随闭包语法如何与 PublicSubject<Void>.subscribe 一起使用?

每次点击应用程序图标时,iOS 13 应用程序都会请求一个新场景

ios - 如何在 iOS 8 的全屏模式下在 UIWebView Player 中接收通知?

iOS-图像未显示自定义单元格(Swift)