RxSwift+Alamofire 自定义映射器错误处理

Posted

技术标签:

【中文标题】RxSwift+Alamofire 自定义映射器错误处理【英文标题】:RxSwift+Alamofire custom mapper error handling 【发布时间】:2019-10-14 01:26:59 【问题描述】:

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 块,我的策略是什么?

【问题讨论】:

【参考方案1】:

您可以在 rxSwift 中使用 ma​​terialize 函数。它将任何 Observable 转换为其事件的 Observable。这样你会听到Observable&lt;Event&lt;Int&gt;&gt; 而不是Observable&lt;Int&gt;。从平面图中抛出的任何错误都将被捕获为订阅块的 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 自定义映射器错误处理的主要内容,如果未能解决你的问题,请参考以下文章

哪个是 xcode 7.2 支持的 alamofire 对象映射器和 alamofire pod 版本

Alamofire.request 不与自定义对象映射

如果映射器在中途失败并且 Hadoop 重试该映射器,自定义计数器会发生啥

双层设备映射器 - 自定义 dm-crypt

keycloak 从自定义协议映射器抛出身份验证错误

无法在 Sqoop 导出中自定义的映射器数量