Bry*_*han 7 json swift codable decodable
鉴于以下JSON文档,我想创建一个struct包含四个属性:filmCount(Int),year(Int),category(String)和actor(Actor数组).
{
"filmCount": 5,
"year": 2018,
"category": "Other",
"actors":{
"nodes":[
{
"actor":{
"id":0,
"name":"Daniel Craig"
}
},
{
"actor":{
"id":1,
"name":"Naomie Harris"
}
},
{
"actor":{
"id":2,
"name":"Rowan Atkinson"
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
PlacerholderData是一个存储三个主要属性和actor列表的结构,这些属性应该从JSON对象nodes的actors属性中的嵌套容器中检索.
PlacerholderData:
struct PlaceholderData: Codable {
let filmCount: Int
let year: Int
let category: String
let actors: [Actor]
}
Run Code Online (Sandbox Code Playgroud)
Actor.swift:
struct Actor: Codable {
let id: Int
let name: String
}
Run Code Online (Sandbox Code Playgroud)
我试图通过提供我自己init的手动初始化解码器容器中的值来做到这一点.如何在不必拥有存储nodes对象的中间结构的情况下解决此问题?
您可以使用 nestedContainer(keyedBy :)和nestedUnkeyedContainer(forKey :)这样对嵌套数组和字典进行解码,以将其转换为所需的结构。您在init(decoder:)中的解码可能看起来像这样,
用于解码的演员扩展,
extension Actor: Decodable {
enum CodingKeys: CodingKey { case id, name }
enum ActorKey: CodingKey { case actor }
init(from decoder: Decoder) throws {
let rootKeys = try decoder.container(keyedBy: ActorKey.self)
let actorContainer = try rootKeys.nestedContainer(keyedBy: CodingKeys.self,
forKey: .actor)
try id = actorContainer.decode(Int.self,
forKey: .id)
try name = actorContainer.decode(String.self,
forKey: .name)
}
}
Run Code Online (Sandbox Code Playgroud)
用于解码的PlaceholderData扩展,
extension PlaceholderData: Decodable {
enum CodingKeys: CodingKey { case filmCount, year, category, actors }
enum NodeKeys: CodingKey { case nodes }
init(from decoder: Decoder) throws {
let rootContainer = try decoder.container(keyedBy: CodingKeys.self)
try filmCount = rootContainer.decode(Int.self,
forKey: .filmCount)
try year = rootContainer.decode(Int.self,
forKey: .year)
try category = rootContainer.decode(String.self,
forKey: .category)
let actorsNode = try rootContainer.nestedContainer(keyedBy: NodeKeys.self,
forKey: .actors)
var nodes = try actorsNode.nestedUnkeyedContainer(forKey: .nodes)
var allActors: [Actor] = []
while !nodes.isAtEnd {
let actor = try nodes.decode(Actor.self)
allActors += [actor]
}
actors = allActors
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以像这样解码
let decoder = JSONDecoder()
do {
let placeholder = try decoder.decode(PlaceholderData.self, from: jsonData)
print(placeholder)
} catch {
print(error)
}
Run Code Online (Sandbox Code Playgroud)
在这里,基本思想是使用nestedContainer(keyedBy :)解码字典容器,并使用nestedUnkeyedContainer(forKey :)解码数组容器。
| 归档时间: |
|
| 查看次数: |
2301 次 |
| 最近记录: |