使用 Codable 或 ObjectMapper 映射通用 API 响应
Posted
技术标签:
【中文标题】使用 Codable 或 ObjectMapper 映射通用 API 响应【英文标题】:Mapping Generic API Response Using Codable or ObjectMapper 【发布时间】:2019-06-21 03:57:24 【问题描述】:我在使用可编码或对象映射器将通用 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 : ??
我将如何构造我的基类以使用一个类来处理这些响应,或者我将构造不同的类只是为了根据值更改“数据”类型?
我们将不胜感激任何形式的帮助或建议。
谢谢
【问题讨论】:
***.com/questions/52681385/… 【参考方案1】:为你的结构创建通用约束,表示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_response
转换为 httpResponse
然后在解码时指定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)
【讨论】:
【参考方案2】:考虑到user
、countries
、locations
是可解码的,您的解码方法和APIResponse
将如下所示,
struct APIResponse<T: Decodable>: Decodable
var data: T?
var code: Int
var success: Bool
var http_response: Int
func decode<T: Decodable>(data: Data, ofType: T.Type) -> T?
do
let decoder = JSONDecoder()
let res = try decoder.decode(APIResponse<T>.self, from: data)
return res.data
catch let parsingError
print("Error", parsingError)
return nil
用法
let data = Data() // From the network api
//User
let user = decode(data, ofType: User.self)
// Countries
let countries = decode(data, ofType: [Country].self)
// Locations
let locations = decode(data, ofType: [Location].self)
【讨论】:
以上是关于使用 Codable 或 ObjectMapper 映射通用 API 响应的主要内容,如果未能解决你的问题,请参考以下文章
如果某些东西符合 Codable ,它会永远无法被编码或解码吗?
FullAuditedEntity、ObjectMapper:创建新条目或删除时的 CreatorUserId Null
Swift:如何将带有 Alamofilre 或 SwiftyJSON 的 JSON 字符串转换为 ObjectMapper?