如何解决如何在Alamofire 5中解码错误的内容?
我正在尝试将项目从Alamofire 4.9迁移到5.3,并且在错误处理方面遇到了困难。我想尽可能多地使用Decodable
,但是当一切顺利时,我的API端点将返回一个JSON结构,而当出现错误时,API端点将返回一个不同的JSON结构,所有端点上的所有错误均相同。我的代码中对应的Codable
是ApiError
。
我想创建一个自定义响应序列化器,该序列化器可以给我一个Result<T,ApiError>
而不是默认的Result<T,AFError>
。我发现this article似乎可以解释一般过程,但是其中的代码无法编译。
如何创建这样的自定义ResponseSerializer
?
解决方法
10
有一个要求。在很大程度上,您可以复制现有的序列化程序。例如,如果您想解析CSV(不检查响应):
1
您可以在Alamofire's documentation中阅读更多内容。
,我最终将其与以下ResponseSerializer一起使用:
struct APIError: Error,Decodable {
let message: String
let code: String
let args: [String]
}
final class TwoDecodableResponseSerializer<T: Decodable>: ResponseSerializer {
lazy var decoder: JSONDecoder = {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return decoder
}()
private lazy var successSerializer = DecodableResponseSerializer<T>(decoder: decoder)
private lazy var errorSerializer = DecodableResponseSerializer<APIError>(decoder: decoder)
public func serialize(request: URLRequest?,response: HTTPURLResponse?,data: Data?,error: Error?) throws -> Result<T,APIError> {
guard error == nil else { return .failure(APIError(message: "Unknown error",code: "unknown",args: [])) }
guard let response = response else { return .failure(APIError(message: "Empty response",code: "empty_response",args: [])) }
do {
if response.statusCode < 200 || response.statusCode >= 300 {
let result = try errorSerializer.serialize(request: request,response: response,data: data,error: nil)
return .failure(result)
} else {
let result = try successSerializer.serialize(request: request,error: nil)
return .success(result)
}
} catch(let err) {
return .failure(APIError(message: "Could not serialize body",code: "unserializable_body",args: [String(data: data!,encoding: .utf8)!,err.localizedDescription]))
}
}
}
extension DataRequest {
@discardableResult func responseTwoDecodable<T: Decodable>(queue: DispatchQueue = DispatchQueue.global(qos: .userInitiated),of t: T.Type,completionHandler: @escaping (Result<T,APIError>) -> Void) -> Self {
return response(queue: .main,responseSerializer: TwoDecodableResponseSerializer<T>()) { response in
switch response.result {
case .success(let result):
completionHandler(result)
case .failure(let error):
completionHandler(.failure(APIError(message: "Other error",code: "other",args: [error.localizedDescription])))
}
}
}
}
然后,我可以这样调用我的API:
AF.request(request).validate().responseTwoDecodable(of: [Item].self) { response in
switch response {
case .success(let items):
completion(.success(items))
case .failure(let error): //error is an APIError
log.error("Error while loading items: \(String(describing: error))")
completion(.failure(.couldNotLoad(underlyingError: error)))
}
}
我只是认为任何200-299范围之外的状态代码都对应一个错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。