Swift 4 Codable; How to decode object with single root-level key

前端 未结 4 919
暖寄归人
暖寄归人 2020-12-02 13:21

I\'m using the Swift 4 Codable protocol with JSON data. My data is formatted such that there is a single key at the root level with an object value containing t

4条回答
  •  温柔的废话
    2020-12-02 13:42

    Ollie's answer is definitely the best way to go for this case, but it does push some knowledge into the caller, which may be undesirable. It also isn't very flexible. I still think it's a great answer and exactly what you want here, but this is a nice simple example to explore custom structural encoding.

    How can we make this work correctly:

    let user = try? JSONDecoder().decode(User.self, from: json)
    

    We can't use the default conformances anymore. We have to build our own decoder. That's slightly tedious, but not difficult. First, we need to encode the structure into CodingKeys:

    struct User {
        let id: Int
        let username: String
    
        enum CodingKeys: String, CodingKey {
            case user // The top level "user" key
        }
    
        // The keys inside of the "user" object
        enum UserKeys: String, CodingKey {
            case id
            case username
        }
    }
    

    With that, we can decode User by hand by pulling out the nested container:

    extension User: Decodable {
        init(from decoder: Decoder) throws {
    
            // Extract the top-level values ("user")
            let values = try decoder.container(keyedBy: CodingKeys.self)
    
            // Extract the user object as a nested container
            let user = try values.nestedContainer(keyedBy: UserKeys.self, forKey: .user)
    
            // Extract each property from the nested container
            id = try user.decode(Int.self, forKey: .id)
            username = try user.decode(String.self, forKey: .username)
        }
    }
    

    But I'd absolutely do it Ollie's way for this problem.

    For much more on this see Encoding and Decoding Custom Types.

提交回复
热议问题