【问题标题】:RxAlamofire - how to get the response on error?RxAlamofire - 如何获得错误响应?
【发布时间】: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)")
      }
    }
  }
)

【问题讨论】:

    标签: rxalamofire


    【解决方案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
    

    【讨论】:

    • 任何其他溶液
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 2019-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    相关资源
    最近更新 更多