在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)")
}
}
}
)
答案 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