Using Codable on a dynamic type/object

前端 未结 2 370
南方客
南方客 2020-12-03 05:54

Hi I have the following structure nested in a bigger structure that is returned from an api call but I can\'t manage to encode/decode this part. The problem I am having is t

2条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-03 06:39

    Since you linked to my answer to another question, I will expand that one to answer yours.

    Truth is, all keys are known at runtime if you know where to look:

    struct GenericCodingKeys: CodingKey {
        var intValue: Int?
        var stringValue: String
    
        init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" }
        init?(stringValue: String) { self.stringValue = stringValue }
    
        static func makeKey(name: String) -> GenericCodingKeys {
            return GenericCodingKeys(stringValue: name)!
        }
    }
    
    
    struct MyModel: Decodable {
        var current: String
        var hash: String
        var values: [String: String]
    
        private enum CodingKeys: String, CodingKey {
            case current
            case hash
            case values
        }
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            current = try container.decode(String.self, forKey: .current)
            hash = try container.decode(String.self, forKey: .hash)
    
            values = [String: String]()
            let subContainer = try container.nestedContainer(keyedBy: GenericCodingKeys.self, forKey: .values)
            for key in subContainer.allKeys {
                values[key.stringValue] = try subContainer.decode(String.self, forKey: key)
            }
        }
    }
    

    Usage:

    let jsonData = """
    {
        "current": "a value",
        "hash": "a value",
        "values": {
            "key1": "customValue",
            "key2": "customValue"
        }
    }
    """.data(using: .utf8)!
    
    let model = try JSONDecoder().decode(MyModel.self, from: jsonData)
    

提交回复
热议问题