RxSwift+Alamofire 自定义映射器错误处理
RxSwift+Alamofire custom mapper error handling
RxSwift 还有一个关于错误处理的问题:
我是这样使用Alamofire+RxAlamofire的:
SessionManager.default.rx.responseJSON(.post, url, parameters:params)
示例:
func login() -> Observable<Int> {
let urlString = ...
let params = ...
return SessionManager.default.rx.responseJSON(.post, url, parameters:params)
.rxJsonDefaultResponse()
.map({ (data) in
data["clientId"] as! Int
})
}
....
extension ObservableType where Element == (HTTPURLResponse, Any) {
func rxJsonDefaultResponse() -> Observable<Dictionary<String, Any>> {
return self.asObservable().map { data -> Dictionary<String, Any> in
if... //error chechings
throw NSError(domain: ..,
code: ...,
userInfo: ...)
}
...
return json
}
}
}
使用:
loginBtn.rx.tap
.flatMap{ _ in
provider.login()
}.subscribe(onNext: { id in
...
}, onError: { (er) in
ErrorPresentationHelper.showErrorAlert(for: er)
})
.disposed(by: bag)
因此,如果发生错误,一切都会按预期进行:显示错误警报并 'loginBtn.rx.tap' 已处理,但我需要它仍然存在,如果我想使用 onError 块,我的策略是什么?
您可以在 rxSwift 中使用 materialize 函数。它会将任何 Observable 转换为其事件的 Observable。这样你就会听到 Observable<Event<Int>>
而不是 Observable<Int>
。从平面图抛出的任何错误都将在订阅块的 onNext 中作为错误事件被捕获,并可以在那里进行处理。而且您的订阅仍然有效。示例代码如下。
button.rx.tap.flatMap { _ in
return Observable.just(0)
.flatMap { _ -> Observable<Int> in
provider.login()
}.materialize()
}.subscribe(onNext: { event in
switch event {
case .next:
if let value = event.element {
print(value) //You will be getting your value here
}
case .error:
if let error = event.error {
print(error.localizedDescription) //You will be getting your captured error here
}
case .completed:
print("Subscription completed")
}
}) {
print("Subscription disposed")
}.disposed(by: disposeBag)
希望对您有所帮助。您可以签出实现扩展 here.
RxSwift 还有一个关于错误处理的问题:
我是这样使用Alamofire+RxAlamofire的:
SessionManager.default.rx.responseJSON(.post, url, parameters:params)
示例:
func login() -> Observable<Int> {
let urlString = ...
let params = ...
return SessionManager.default.rx.responseJSON(.post, url, parameters:params)
.rxJsonDefaultResponse()
.map({ (data) in
data["clientId"] as! Int
})
}
....
extension ObservableType where Element == (HTTPURLResponse, Any) {
func rxJsonDefaultResponse() -> Observable<Dictionary<String, Any>> {
return self.asObservable().map { data -> Dictionary<String, Any> in
if... //error chechings
throw NSError(domain: ..,
code: ...,
userInfo: ...)
}
...
return json
}
}
}
使用:
loginBtn.rx.tap
.flatMap{ _ in
provider.login()
}.subscribe(onNext: { id in
...
}, onError: { (er) in
ErrorPresentationHelper.showErrorAlert(for: er)
})
.disposed(by: bag)
因此,如果发生错误,一切都会按预期进行:显示错误警报并 'loginBtn.rx.tap' 已处理,但我需要它仍然存在,如果我想使用 onError 块,我的策略是什么?
您可以在 rxSwift 中使用 materialize 函数。它会将任何 Observable 转换为其事件的 Observable。这样你就会听到 Observable<Event<Int>>
而不是 Observable<Int>
。从平面图抛出的任何错误都将在订阅块的 onNext 中作为错误事件被捕获,并可以在那里进行处理。而且您的订阅仍然有效。示例代码如下。
button.rx.tap.flatMap { _ in
return Observable.just(0)
.flatMap { _ -> Observable<Int> in
provider.login()
}.materialize()
}.subscribe(onNext: { event in
switch event {
case .next:
if let value = event.element {
print(value) //You will be getting your value here
}
case .error:
if let error = event.error {
print(error.localizedDescription) //You will be getting your captured error here
}
case .completed:
print("Subscription completed")
}
}) {
print("Subscription disposed")
}.disposed(by: disposeBag)
希望对您有所帮助。您可以签出实现扩展 here.