处理 UITableView 绑定中的连接错误(Moya、RxSwift、RxCocoa)
Handle Connection Error in UITableView Binding (Moya, RxSwift, RxCocoa)
我正在使用 RxCoCoa 和 RxSwift 进行 UITableView 竞标。
问题是当连接丢失或其他连接错误时,除了服务器错误(我处理了它们)我的应用程序由于下面提到的绑定错误而崩溃。我的问题是如何处理连接错误?
fileprivate func getNextState() {
showFullPageState(State.LOADING)
viewModel.getProductListByID(orderGroup: OrderGroup.SERVICES.rawValue)
.do(onError: {
showStatusError(error: [=10=])
self.showFullPageState(State.CONTENT)
})
.filter {
[=10=].products != nil
}
.map {
[=10=].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: [=11=].data)
}.asObservable()
}
我将 Moya 用于我的网络层,如下所示:
func getProductsById(query: [String: String]) -> Single<Response> {
return provider.rx.request(.getProductsById(query))
.filterSuccessfulStatusCodes()
}
您没有在任何地方处理错误。我的意思是您承认 do
运算符中的错误,但实际上并没有处理它,只是允许它传递给无法处理错误的 table 视图。
查找 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 { [=10=].products != nil }
.map { [=10=].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)
}
按照您设置代码的方式,用户重试该服务的唯一方法是再次调用该函数。如果你想让用户在更具声明性的庄园中重试,你需要将链绑定到用户可以触发的可观察对象。
我正在使用 RxCoCoa 和 RxSwift 进行 UITableView 竞标。 问题是当连接丢失或其他连接错误时,除了服务器错误(我处理了它们)我的应用程序由于下面提到的绑定错误而崩溃。我的问题是如何处理连接错误?
fileprivate func getNextState() {
showFullPageState(State.LOADING)
viewModel.getProductListByID(orderGroup: OrderGroup.SERVICES.rawValue)
.do(onError: {
showStatusError(error: [=10=])
self.showFullPageState(State.CONTENT)
})
.filter {
[=10=].products != nil
}
.map {
[=10=].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: [=11=].data)
}.asObservable()
}
我将 Moya 用于我的网络层,如下所示:
func getProductsById(query: [String: String]) -> Single<Response> {
return provider.rx.request(.getProductsById(query))
.filterSuccessfulStatusCodes()
}
您没有在任何地方处理错误。我的意思是您承认 do
运算符中的错误,但实际上并没有处理它,只是允许它传递给无法处理错误的 table 视图。
查找 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 { [=10=].products != nil }
.map { [=10=].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)
}
按照您设置代码的方式,用户重试该服务的唯一方法是再次调用该函数。如果你想让用户在更具声明性的庄园中重试,你需要将链绑定到用户可以触发的可观察对象。