RxAlamofire - 如何获得错误响应?

Posted

技术标签:

【中文标题】RxAlamofire - 如何获得错误响应?【英文标题】:RxAlamofire - how to get the response on error? 【发布时间】:2018-04-20 10:15:45 【问题描述】:

当 RxAlamofire 调用中发生错误时,我需要响应正文。我见过this hack,但我想知道是否有更清洁的方法。

受此启发,我用类似的 hack 创建了这个RxAlamofire fork。有了它,错误通常是DataResponseError 的一个实例,所以你可以这样做:

RxAlamofire.data(method, url).subscribe(

  onError:  error in

    if let error = error as? DataResponseError<Data> 

      // Get response body (in this case, convert it to a String)
      if let data = error.response.data 
          let message = String(data: data, encoding: String.Encoding.utf8)
          print("Message: \(message)")
      

      // Get status code
      if let statusCode = error.response.response?.statusCode 
          print("Status code: \(statusCode)")
      
    
  
)

【问题讨论】:

【参考方案1】:

问题描述。我正在使用 RxAlamofire 发出网络请求,我需要从错误响应的正文中获取信息。

我通过以下方式进行了破解:

添加了一个 PError:

import UIKit
import Alamofire
import ObjectMapper

class PError: Error, Mappable 
    var message: String?
    var statusCode: Int?

    required init?(map: Map) 

    

    func mapping( map: Map) 
        message <- map["error.message"]
        statusCode <- map["error.statusCode"]
    

现在向 DataRequest 添加了这样的扩展:

import Alamofire
import ObjectMapper

    extension DataRequest 
        //Overriding several methods from Alamofire Validation
        @discardableResult
        public func validate<S: Sequence>(statusCode acceptableStatusCodes: S) -> Self where S.Iterator.Element == Int 
            return validate  [unowned self] _, response, bodyData in
                return self.validate(statusCode: acceptableStatusCodes, response: response, bodyData: bodyData)
            
        

        //Overriding several methods from Alamofire Validataion
        fileprivate func validate<S: Sequence>(
            statusCode acceptableStatusCodes: S,
            response: HTTPURLResponse, bodyData: Data?)
            -> ValidationResult
            where S.Iterator.Element == Int
        
            if acceptableStatusCodes.contains(response.statusCode) 
                return .success
             else 
                var error: Error = AFError.responseValidationFailed(reason: AFError.ResponseValidationFailureReason.unacceptableStatusCode(code: response.statusCode))
                if let bodyData = bodyData 
                    if let jsonString = String(data: bodyData, encoding: .utf8) 
                        if let errorNew = Mapper<PError>().map(JSONString: jsonString)
                        
                            error = errorNew
                        
                    
                
                return .failure(error)
            
        
    

接下来,您可以在代码中的某处使用此自定义错误对象:

if let err = error as? PError 
                status = err.message ?? "No message in the error description"
            
            else

【讨论】:

任何其他溶液

以上是关于RxAlamofire - 如何获得错误响应?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3、RxAlamofire 和映射到自定义对象

使用 RxAlamofire 创建 Observable 包含网络请求的结果

RxAlamofire + 组合信号

RxAlamofire 扩展在一处处理错误

如何使用 RxAlamofire 下载图像

如何在 swift4 中使用 Rxalamofire 发送 URL 请求