繁体   English   中英

如何使用alamofire httpstatusCode

[英]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 响应的对象,有几种方法:

  1. 使用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) } }
  2. 如果需要,您可以编写自己的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM