Swift 4 Decodable: struct from nested array

本小妞迷上赌 提交于 2019-12-03 16:11:45

You can use nestedContainer(keyedBy:) and nestedUnkeyedContainer(forKey:) for decoding nested array and dictionary like this to turn it into your desired structure. Your decoding in init(decoder: ) might look something like this,

Actor extension for decoding,

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 for decoding,

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
    }
}

Then, you can decode it like this,

let decoder = JSONDecoder()
do {
    let placeholder = try decoder.decode(PlaceholderData.self, from: jsonData)
    print(placeholder)
} catch {
    print(error)
}

Here, the basic idea is to decode dictionary container using nestedContainer(keyedBy:) and array container using nestedUnkeyedContainer(forKey:)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!