Skip to content

Instantly share code, notes, and snippets.

@atierian
Created September 7, 2021 15:24
Show Gist options
  • Save atierian/29d06799ec99ecd8b9a2de834717c6be to your computer and use it in GitHub Desktop.
Save atierian/29d06799ec99ecd8b9a2de834717c6be to your computer and use it in GitHub Desktop.
Top Level Key Decoding
struct AnyCodingKey: CodingKey {
var stringValue: String
var intValue: Int?
init(stringValue: String) {
self.stringValue = stringValue
self.intValue = nil
}
init(intValue: Int) {
self.stringValue = "\(intValue)"
self.intValue = intValue
}
}
extension AnyCodingKey: ExpressibleByStringLiteral {
init(stringLiteral value: StringLiteralType) {
self.init(stringValue: value)
}
}
private let topLevelKey = CodingUserInfoKey(rawValue: "topLevelKey")!
private struct Wrapper<T: Decodable>: Decodable {
let value: T
init(from decoder: Decoder) throws {
let key = decoder.userInfo[topLevelKey] as! AnyCodingKey
let container = try decoder.container(keyedBy: AnyCodingKey.self)
value = try container.decode(T.self, forKey: key)
}
}
extension JSONDecoder {
func decode<T: Decodable>(_ type: T.Type, key: AnyCodingKey, from data: Data) throws -> T {
userInfo[topLevelKey] = key
return try decode(Wrapper.self, from: data).value
}
}
struct User: Codable {
let age: Int
let name: String
}
let data = """
{
"users": [
{
"name": "Ian",
"age": 31
},
{
"name": "Michael",
"age": 42
}
]
}
""".data(using: .utf8)!
let users = try JSONDecoder().decode([User].self, key: "users", from: data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment