首页 > 解决方案 > 使用 Codable 或 ObjectMapper 映射通用 API 响应

问题描述

我在使用可编码或对象映射器将通用 api 响应映射到模型类方面面临挑战。假设我有针对不同 api 的这些 api 响应。

{
  "code" : 0, 
  "http_response" : 200,
  "success" : true, 
  "data" : user
}

{
  "code" : 0, 
  "http_response" : 200,
  "success" : true, 
  "data" : locations
}

{
  "code" : 0, 
  "http_response" : 200,
  "success" : true, 
  "data" : countries
}

这里用户、位置和国家是单独的可编码/映射器类。

我将不得不构建一个这样的类

struct APIResponse : Codable {
    let success : Bool?
    let http_response : Int?
    let code : Int?
    let data : ??
}

我将如何构造我的基类以使用一个类来处理这些响应,或者我将构造不同的类只是为了根据值更改“数据”类型?

任何形式的帮助或建议将不胜感激。

谢谢

标签: iosswiftmappingcodableobjectmapper

解决方案


为你的结构做通用约束,它说T必须符合Decodable然后使用这个类型来指定类型data

struct APIResponse<T: Decodable>: Decodable {
    var code, httpResponse: Int
    var success: Bool
    var data: T
}

struct User: Decodable {
    var name: String
}

请注意,我更改了httpResponse参数的名称,因为我使用keyDecodingStrategy的是转换http_responsehttpResponse


然后在解码时指定类型T

单个对象

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

do {
    let responses = try decoder.decode([APIResponse<User>].self, from: data)
    let user = responses[0].data /* data of type `User` of specific response */
} catch { print(error) }

对象数组

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

do {
    let responses = try decoder.decode([APIResponse<[User]>].self, from: data)
    let users = responses[0].data /* data of type `[User]` of specific response */
} catch { print(error) }

推荐阅读