如何使用alamofire httpstatuscode

发布于 2025-02-02 05:20:23 字数 1656 浏览 4 评论 0原文

我想要在httpstatuscode

Server返回

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)
            }
        }

尝试使用此代码转换响应的响应,

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)
            }

但是这种方式,无论状态密码返回A和B,

我都想要 StautScode == 200返回A或 状态密码400 ..&lt; 500返回b

我该怎么办?

I want a diffrerent responseDecodable on the httpStatusCode

server return

if statusCode == 200
resonseBody
{id: number}

if statusCode 400..<500
resonseBody
{
code: String
timestamp: String
message: String
}

so now my code is

 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)
            }
        }

I try this code convert 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)
            }

but this way Regardless statusCode return both a and b

I want
stautsCode == 200 return a or
statusCode 400..<500 return b

What should I Do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

记忆之渊 2025-02-09 05:20:23

Afaik,Alamofire没有“为成功的一个对象解码一个对象,而另一个为失败”实现。您必须自己做。

如果您真的想要一个不同的对象来响应2xx响应,而对于4xx响应,则有几种方法:

  1. 使用validate处理2xx响应,并在错误处理程序中手动解码4xx响应。

      af.request(url,方法:.post,参数:参数,标题:标题:标题)
        .Validate(状态代码:200 ..&lt; 300)//仅为我们自动淘汰2xx;处理“失败”处理程序中的4xx响应
        。
            切换响应。recult {
            案例.failure(让错误):
                警卫
                    LET STATUS CODE = RESPONDS.Response?.StatusCode,
                    400 ..&lt; 500〜 =状态代码,
                    令data = wendesp.data,
                    让apierror =尝试吗? jsondecoder()。解码(apierRorresponse.self,来自:数据)
                别的 {
                    print(“其他错误:”,错误)//没有解析`apierRorresponse`对象,所以显然其他错误
                    返回
                }
    
                print(“ apierror:”,apierror)//这是我们解析的API错误对象
    
            case .success(让foo):
                打印(“成功:”,foo)
            }
        }
     
  2. 如果愿意,可以将自己的wenderserializer写入2xx和4xx响应的方式不同:


    令代码:字符串
    令时间戳:字符串
    让消息:字符串
    }

    最终类apirepsesserializer&lt; t:可解码&gt;:wendesserializer {
    懒惰的var decoder = jsondecoder()

    私人懒惰var successerializer = decodableResponseserializer&lt; t&gt;(解码器:解码器)
    私有懒惰的var ryrorSerializer =解码器处理器&lt; apierRorresponse&gt;(解码器:解码器)

    public func序列化(请求:urlrequest?,响应:httpurlresponse?,data:data?error:错误:错误?) t {
    如果让错误=错误{投掷错误}

    Guard Response =响应else {投掷Urlerror(.badserverresponse)}}

    切换响应。STATUSCODE{
    案例400 ..&lt; 500:
    令apierRobject =尝试errorSerializer.Serialize(请求:请求,响应:响应,数据:数据,错误:nil)
    投掷apierRorobject

    默认:
    返回尝试Successerializer.Serialize(请求:请求,响应:响应,数据:数据,错误:nil)
    }
    }
    }

    然后您可以做:

      af.request(url,方法:.post,参数:参数,标题:标题:标题)
        。
            切换响应。recult {
            case .failure(.responseserializationFailed(原因:.customSerializationFailed(错误:让ApierRobject))):
                打印(“ API响应错误:”,ApierRorObject)
    
            案例.failure(让错误):
                打印(“其他错误:”,错误)
    
            case .success(让foo):
                打印(“成功:”,foo)
            }
        }
     

    我发现解析的错误对象的嵌套有点乏味,但是它确实将2xx vs 4xx逻辑抽象为响应>响应/wendersedecdecoder完成处理程序。

在这两种情况下,我都将所有2xx响应视为成功,不仅是200个。有些服务器返回2xx代码,而不是200个代码。

AFAIK, Alamofire does not have a “decode one object for success and another for failure” implementation. You'll have to do this yourself.

If you really want a one distinct object for 2xx responses and another for 4xx responses, there are a few approaches:

  1. Use validate to handle the 2xx responses, and manually decode 4xx responses in the error handler.

    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. If you want, you could write your own ResponseSerializer to parse 2xx and 4xx responses differently:

    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)
            }
        }
    }
    

    And then you can do:

    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)
            }
        }
    

    I find the nesting of the parsed error object to be a little tedious, but it does abstract the 2xx vs 4xx logic out of the response/responseDecoder completion handler.

In both of these, I'm considering all 2xx responses as success, not just 200. Some servers return 2xx codes other than just 200.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文