RxSwift使可观察触发对象

问题描述 投票:1回答:1

我有一个BehaviorSubject,通过RxDataSources绑定了我的表视图。

此外,我还需要刷新以创建一个可观察的对象,该对象可更新数据并更新BehaviorSubject中的数据,以便我的UITableView正确更新。

现在的问题是,每当我的API调用失败时,如何处理错误处理?

我想到的几个选项是:

  1. 订阅观察者的onError并呼叫我的onErrorBehaviorSubject \
  2. 以某种方式尝试concat?或bind(to: ..)
  3. [我的ViewController中的另一个订阅者订阅,除了我的表视图订阅了BehaviorSubject

有什么建议吗?

ios swift observable rx-swift reactivex
1个回答
0
投票

理想情况下,您根本不会使用BehaviorSubject。从Intro to Rx书中:

主题的使用应很大程度上保留在样本和测试领域。主题是开始使用Rx的好方法。它们减少了新开发人员的学习难度,但是却带来了一些问题...

更好的方法是在viewDidLoad(或从viewDidLoad调用的函数)中执行以下操作:

let earthquakeData = Observable.merge(
    tableView.refreshControl!.rx.controlEvent(.valueChanged).asObservable(),
    rx.methodInvoked(#selector(UIViewController.viewDidAppear(_:))).map { _ in }
)
    .map { earthquakeSummary /* generate URLRequest */ }
    .flatMapLatest { request in
        URLSession.shared.rx.data(request: request)
            .materialize()
    }
    .share(replay: 1)

earthquakeData
    .compactMap { $0.element }
    .map { Earthquake.earthquakes(from: $0) }
    .map { $0.map { EarthquakeCellDisplay(earthquake: $0) } }
    .bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: EarthquakeTableViewCell.self)) { _, element, cell in
        cell.placeLabel.text = element.place
        cell.dateLabel.text = element.date
        cell.magnitudeLabel.text = element.magnitude
        cell.magnitudeImageView.image = element.imageName.isEmpty ? UIImage() : UIImage(named: element.imageName)
    }
    .disposed(by: disposeBag)

earthquakeData
    .compactMap { $0.error }
    .map { (title: "Error", message: $0.localizedDescription) }
    .bind { [weak self] title, message in
        self?.presentAlert(title: title, message: message, animated: true)
    }
    .disposed(by: disposeBag)

materialize()运算符将Event.error(Error)结果转换为Event.next(.error(Error)),这样就不会破坏链。 .compactMap { $0.element }仅发出成功结果,而.compactMap { $0.error }仅发出错误。

上面的代码改编自我的RxEarthquake示例。

© www.soinside.com 2019 - 2024. All rights reserved.