RxAlamofire - 如何获得错误响应?

时间:2018-04-20 10:15:46

标签: rxalamofire

在RxAlamofire调用中发生错误时,我需要响应正文。我已经看过this 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 个答案:

答案 0 :(得分:2)

问题说明。我使用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