当 RxAlamofire 调用发生错误时,我需要响应正文。我见过这个黑客,但我想知道是否有更清洁的方法。
受它的启发,我使用类似的 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)")
}
}
}
)
Run Code Online (Sandbox Code Playgroud)
问题描述。我正在使用 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"]
}
}
Run Code Online (Sandbox Code Playgroud)
现在向 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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,在代码中的某个位置,您将能够使用此自定义错误对象:
if let err = error as? PError {
status = err.message ?? "No message in the error description"
}
else
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1477 次 |
| 最近记录: |