使用 RxSwift 和 MVVM 处理错误
Handling error with RxSwift and MVVM
我正在尝试使用 RxSwift 和 MVVM 构建一个不错的架构。我想知道如何正确处理来自可观察对象的错误。
我的 ViewModel 看起来像:
class MapViewModel {
private let disposeBag = DisposeBag()
private let listObservable: Observable<[MyObject]>
let list: Variable<[MyObject]>
let showError: Variable<Bool>
init() {
self.listObservable = getObservable().shareReplay(1)
self.list = Variable<[MyObject]>([])
self.listObservable
.bind(to: list)
.addDisposableTo(self.disposeBag)
self.showError = Variable<Bool>(false)
self.listObservable
.subscribe(
onError: { [weak self] error in
print("Error downloading: \(error)")
self?.showError.value = true
}).addDisposableTo(disposeBag)
}
}
我认为这是正确的做法:明确分离关注点,并共享可观察对象以防止多次调用 REST 端点。
然而,当我这样做时——可观察对象发送了一个错误——我从 RxSwift 得到了一个 fatalError,因为错误没有在 bind()
调用中处理。
为了解决这个问题,我将代码更改为:
self.listObservable
.subscribe(
onNext: { [weak self] list in
self?.list.value = list
},
onError: { [weak self] error in
print("Error downloading: \(error)")
self?.showError.value = true
}).addDisposableTo(disposeBag)
这对我来说似乎不太清楚。正确的方法应该是什么?
我认为 Variable
s 的使用会让你失望。尽可能避免使用它们。
我对这段代码的印象:
创建视图模型时,它会调用 getObservable()
。
没有提供用户输入。
showError
变量似乎被用作触发器而不是实际传递值,因此它应该是 Void 而不是 Bool
我希望这个视图模型看起来更像:
struct MapViewModel {
let list: Observable<[MyObject]>
let showError: Observable<Void>
init() {
let dataResult = getObservable()
.materialize()
.shareReplayLatestWhileConnected()
list = dataResult.map { [=10=].element }
.filter { [=10=] != nil }
.map { [=10=]! }
showError = dataResult.map { [=10=].error }
.filter { [=10=] != nil }
.map { _ in }
}
}
上面的秘诀是使用 materialize
将错误转换为 onNext
事件,以便您可以将其用于触发器。
subscribes/binds 和 dispose 包应该在视图控制器中,而不是在视图模型中。
我正在尝试使用 RxSwift 和 MVVM 构建一个不错的架构。我想知道如何正确处理来自可观察对象的错误。
我的 ViewModel 看起来像:
class MapViewModel {
private let disposeBag = DisposeBag()
private let listObservable: Observable<[MyObject]>
let list: Variable<[MyObject]>
let showError: Variable<Bool>
init() {
self.listObservable = getObservable().shareReplay(1)
self.list = Variable<[MyObject]>([])
self.listObservable
.bind(to: list)
.addDisposableTo(self.disposeBag)
self.showError = Variable<Bool>(false)
self.listObservable
.subscribe(
onError: { [weak self] error in
print("Error downloading: \(error)")
self?.showError.value = true
}).addDisposableTo(disposeBag)
}
}
我认为这是正确的做法:明确分离关注点,并共享可观察对象以防止多次调用 REST 端点。
然而,当我这样做时——可观察对象发送了一个错误——我从 RxSwift 得到了一个 fatalError,因为错误没有在 bind()
调用中处理。
为了解决这个问题,我将代码更改为:
self.listObservable
.subscribe(
onNext: { [weak self] list in
self?.list.value = list
},
onError: { [weak self] error in
print("Error downloading: \(error)")
self?.showError.value = true
}).addDisposableTo(disposeBag)
这对我来说似乎不太清楚。正确的方法应该是什么?
我认为 Variable
s 的使用会让你失望。尽可能避免使用它们。
我对这段代码的印象:
创建视图模型时,它会调用
getObservable()
。没有提供用户输入。
showError
变量似乎被用作触发器而不是实际传递值,因此它应该是 Void 而不是 Bool
我希望这个视图模型看起来更像:
struct MapViewModel {
let list: Observable<[MyObject]>
let showError: Observable<Void>
init() {
let dataResult = getObservable()
.materialize()
.shareReplayLatestWhileConnected()
list = dataResult.map { [=10=].element }
.filter { [=10=] != nil }
.map { [=10=]! }
showError = dataResult.map { [=10=].error }
.filter { [=10=] != nil }
.map { _ in }
}
}
上面的秘诀是使用 materialize
将错误转换为 onNext
事件,以便您可以将其用于触发器。
subscribes/binds 和 dispose 包应该在视图控制器中,而不是在视图模型中。