【问题标题】:Swift/Alamofire 5 ResponseSerializer 通用结构解码
【发布时间】:2022-01-22 12:03:37
【问题描述】:

我正在尝试序列化来自 API 端点的一些 JSON 数据,因为所有端点都具有相同的结构,所以我认为最好实现一些不需要重复的东西再次在代码中。

JSON 响应 1:

{
   "code":1100,
   "message":"Successfully created application",
   "data":{
      "key":116541
   }
}

JSON 响应 2:

{
   "code":1101,
   "message":"Successfully retrived",
   "data":{
      "id":116541,
      "name":"hallow"
   }
}

只有数据会根据 API 端点而改变。他们总是以这种结构出现。

struct RawResponse<T: Decodable>: Decodable {
    let code: Int
    let message: String
    let data: T
}

这是我不知道如何使用 Alamofire 的 DecodableResponseSerializer 解码 RawResponse 的地方。

final class CustomDecodeableResponseSerializer<T: Decodable>: ResponseSerializer {
   //...decoder setup

   //don't work, missing "T" because it's defined in the struct don't know where to add this 
   private lazy var successSerializer = DecodableResponseSerializer<RawResponse>(decoder: decoder)

   //This works as it's just pure struct without generic
   private lazy var errorSerializer = DecodableResponseSerializer<APIError>(decoder: decoder)

   //...public func serialize stuff
}

这是行不通的,因为它要求结构中定义的“T”,而“T”是通过 DataRequest 的扩展传入的

@discardableResult
    func responseCustom<T: Decodable>(queue: DispatchQueue = DispatchQueue.global(qos: .userInitiated), of t: T.Type, completionHandler: @escaping (Result<T, APIError>) -> Void) -> Self {
        return response(queue: .main, responseSerializer: CustomDecodeableResponseSerializer<T>()) { response in
            switch response.result {
            case .success(let result):
                completionHandler(result)
            case .failure(let error):
                completionHandler(.failure(APIError(code: -1, message: error.localizedDescription)))
            }
        }
    }

所以可以这样调用: User 是 JSON“数据”字段的另一个结构体,将被解码为

session.request()
.validate()
.responseCustom(of: User.self){(response) in 
   //do stuff
}

我希望这是有道理的...我知道如果我只是传递 T 而不是制作原始响应结构,我可以在每个响应结构中重复代码和消息,它会起作用。但我试图不在每个响应结构中重复代码和消息。还是有更简单的方法来实现这一点?

【问题讨论】:

    标签: swift struct alamofire decodable


    【解决方案1】:

    您的代码中没有它,但请确保您的 CustomDecodeableResponseSerializer 从其 serialize 方法返回 RawResponse&lt;T&gt;。然后你可以确保你的成功案例的解码器是DecodableResponseSerializer&lt;RawResponse&lt;T&gt;&gt;(decoder: decoder)。

    另外,没有理由使用DispatchQueue.global()。该参数仅控制调用完成处理程序的位置,实际的序列化工作始终在后台执行。

    【讨论】:

    • 你是对的。该死的,我只是放屁,并没有改变返回类型。 IDE 出于稍微不同的原因对我大喊大叫,所以我没有考虑。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    • 2018-11-27
    • 2020-04-20
    • 2023-04-02
    • 2020-07-26
    • 1970-01-01
    • 2021-08-10
    相关资源
    最近更新 更多