[英]how to use alamofire httpstatusCode
我想要 httpStatusCode 上的不同 responseDecodable
服務器返回
if statusCode == 200
resonseBody
{id: number}
if statusCode 400..<500
resonseBody
{
code: String
timestamp: String
message: String
}
所以現在我的代碼是
AF.request(url, method: .post, headers: header).responseData { response in
switch response.result {
case .success(let data) :
guard let response = response.response else {return}
let json = try? JSONSerialization.jsonObject(with: data)
switch response.statusCode {
case 200:
if let json = json as? [String: Any] , let message = json["id"] as? Int{print(message)}
case (400..<500):
if let json = json as? [String: Any] , let message = json["message"] as? String{print(message)}
default:
return
}
case .failure(let err) :
print(err)
}
}
我試試這個代碼轉換 responseDecodable
struct a: Codable {var id: Int}
struct b: Codable{
var code: String
var timestamp: String
var message: String
}
AF.request(url, method: .post, headers: header).responseDecodable(of: a.self) { response in
guard let data = response.value else {return}
print(data)
}
.responseDecodable(of: b.self) { response in
guard let data = response.value else {return}
print(data)
}
但是這樣不管 statusCode 都返回 a 和 b
我想要 statusCode == 200 返回 a 或 statusCode 400..<500 返回 b
我應該怎么辦?
AFAIK,Alamofire 沒有“解碼一個對象成功,另一個對象失敗”的實現。 你必須自己做這件事。
如果您真的想要一個用於 2xx 響應的不同對象和另一個用於 4xx 響應的對象,有幾種方法:
使用validate
處理 2xx 響應,並在錯誤處理程序中手動解碼 4xx 響應。
AF.request(url, method: .post, parameters: parameters, headers: header) .validate(statusCode: 200 ..< 300) // only 2xx are auto-decoded for us; handle 4xx responses in `failure` handler .responseDecodable(of: Foo.self) { response in switch response.result { case .failure(let error): guard let statusCode = response.response?.statusCode, 400 ..< 500 ~= statusCode, let data = response.data, let apiError = try? JSONDecoder().decode(ApiErrorResponse.self, from: data) else { print("other error:", error) // didn't parse `ApiErrorResponse` object, so obviously some other error return } print("apiError:", apiError) // this is our parsed API error object case .success(let foo): print("success:", foo) } }
如果需要,您可以編寫自己的ResponseSerializer
以不同方式解析 2xx 和 4xx 響應:
struct ApiErrorResponse: Decodable, Error { let code: String let timestamp: String let message: String } final class ApiResponseSerializer<T: Decodable>: ResponseSerializer { lazy var decoder = JSONDecoder() private lazy var successSerializer = DecodableResponseSerializer<T>(decoder: decoder) private lazy var errorSerializer = DecodableResponseSerializer<ApiErrorResponse>(decoder: decoder) public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T { if let error = error { throw error } guard let response = response else { throw URLError(.badServerResponse) } switch response.statusCode { case 400 ..< 500: let apiErrorObject = try errorSerializer.serialize(request: request, response: response, data: data, error: nil) throw apiErrorObject default: return try successSerializer.serialize(request: request, response: response, data: data, error: nil) } } }
然后你可以這樣做:
AF.request(url, method: .post, parameters: parameters, headers: header) .response(responseSerializer: ApiResponseSerializer<Foo>()) { response in switch response.result { case .failure(.responseSerializationFailed(reason: .customSerializationFailed(error: let apiErrorObject))): print("api response error:", apiErrorObject) case .failure(let error): print("some other error:", error) case .success(let foo): print("success:", foo) } }
我發現解析錯誤對象的嵌套有點乏味,但它確實從response
/ responseDecoder
完成處理程序中抽象出 2xx 與 4xx 邏輯。
在這兩種情況下,我都認為所有 2xx 響應都是成功的,而不僅僅是 200。一些服務器返回 2xx 代碼,而不僅僅是 200。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.