Обработка ошибки соединения в привязке UITableView (Moya, RxSwift, RxCocoa) - PullRequest
0 голосов
/ 18 ноября 2018

Я использую RxCoCoa и RxSwift для UITableView Biding.проблема заключается в том, что соединение потеряно или другие ошибки соединения, за исключением ошибок сервера (я их обработал), вызывают сбой моего приложения из-за ошибки привязки, упомянутой ниже.мой вопрос, как обрабатывать ошибки подключения?

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()
    }

, и я использую Мойя для моего сетевого уровня, например:

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

enter image description here

1 Ответ

0 голосов
/ 18 ноября 2018

Вы нигде не обрабатываете ошибки.Я имею в виду, что вы признаете ошибку в операторе do, но на самом деле она не обрабатывается, а просто позволяет ей перейти к табличному представлению, которое не может обработать ошибку.

Поисксерия операторов catchError для решения.Вероятно, .catchErrorJustReturn([]) будет всем, что вам нужно.


В комментарии вы сказали:

... Я не хочу возвращать пустой массив в мою таблицу,Я хочу показать ошибку клиенту, и клиент может повторить попытку обслуживания

В этом случае вы должны использовать .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)
}

Способ установки кода, единственный способ для пользователя повторить попытку службы - это снова вызвать функцию.Если вы хотите позволить пользователю повторить попытку в более декларативном поместье, вам нужно привязать цепочку к наблюдаемой, которую пользователь может вызвать.

...