鉴于以下JSON文档,我想创建一个具有四个属性的struct
:filmCount
(Int),year
(Int),category
(String) ,和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"
}
}
]
}
}
PlacerholderData
是一个结构,存储三个主要属性和应该从JSON对象的nodes
属性中的嵌套actors
容器中检索的actor列表。
PlacerholderData:
struct PlaceholderData: Codable {
let filmCount: Int
let year: Int
let category: String
let actors: [Actor]
}
Actor.swift:
struct Actor: Codable {
let id: Int
let name: String
}
我试图通过提供我自己的init
手动初始化解码器容器中的值来实现此目的。如何在不必拥有存储nodes
对象的中间结构的情况下解决此问题?
答案 0 :(得分:3)
您可以使用 nestedContainer(keyedBy :) 和 nestedUnkeyedContainer(forKey :) 来解码嵌套数组和字典,将其转换为您想要的结构。您在 init(decoder :) 中的解码可能看起来像这样,
用于解码的Actor扩展,
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)
}
}
用于解码的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
}
}
然后,您可以像这样解码它,
let decoder = JSONDecoder()
do {
let placeholder = try decoder.decode(PlaceholderData.self, from: jsonData)
print(placeholder)
} catch {
print(error)
}
这里,基本思想是使用 nestedUntaedContainer(keyedBy:)和数组容器使用 nestedUnkeyedContainer(forKey :)
解码字典容器