使用 Codable 投射到对象

Posted

技术标签:

【中文标题】使用 Codable 投射到对象【英文标题】:Casting to object with Codable 【发布时间】:2018-10-09 21:22:00 【问题描述】:

我所有的 JSON 响应都遵循相同的结构:

"success": <http code>,
"data": [

]

发回的data 可能会有所不同。有时它可以包含Users,有时可以包含Comments 等。所以我想创建一个 Codable struct,它可以灵活地处理在data 数组中发送回的各种类型的对象。

这是我目前的struct

struct BasicResponse: Codable 
    let success: Int
    let data: [User]

如您所见,它目前只处理 User 发回的数据。

然后,我像这样(通过 Alamofire/Moya)读取 JSON 数据:

var users = [User]()

let results = try JSONDecoder().decode(BasicResponse.self, from: response.data)

self.users.append(contentsOf: results.data)

如何将我的struct 文件更改为更灵活,然后如何将 JSON 响应转换为所需的对象?

【问题讨论】:

【参考方案1】:

因此,无需经历大量的设计周期,我会考虑尝试 Swift 的通用支持,例如...

struct BasicResponse<DataType>: Codable where DataType: Codable 
    let success: Int
    let data: [DataType]

那你只需要定义你要使用的DataTypes的实现

struct User: Codable 
    var name: String

然后解码...

let decoder = JSONDecoder()
let response = try decoder.decode(BasicResponse<User>.self, from: data)
print(response.data[0].name)

现在,我只是把它扔到一个 Playground 中,并用一些基本数据对其进行了测试......

struct User: Codable 
    var name: String


struct BasicResponse<T>: Codable where T: Codable 
    let success: Int
    let data: [T]


let data = "\"success\": 200, \"data\": [  \"name\":\"hello\" ]".data(using: .utf8)!

let decoder = JSONDecoder()
do 
    let response = try decoder.decode(BasicResponse<User>.self, from: data)
    response.data[0].name
 catch let error 
    print(error)

您可能需要“按摩”设计以更好地满足您的需求,但它可能会给您一个起点

【讨论】:

以上是关于使用 Codable 投射到对象的主要内容,如果未能解决你的问题,请参考以下文章

Codable和CodingKeys

使用 Codable 解析嵌套的 JSON 数据

使用字典/数组初始化符合 Codable 的对象

使用 Codable 或 ObjectMapper 映射通用 API 响应

Swift Codable:标记对象以进行状态恢复

在 swift 中对动态键和动态对象使用 Codable