init(from:)で独自のデコード処理を記述することが出来ます。以下のコードでフラットなJSONからネストしたオブジェクトにデコードすることが出来ます。
struct User: Codable {
struct Address: Codable {
let street: String
let city: String
let state: String
}
let name: String
let address: Address
private enum CodingKeys: String, CodingKey {
case name
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
address = try Address(from: decoder)
}
}
let data = """
{
"name": "rizumita",
"street": "1-2-3 Foo",
"city": "Bar",
"state": "Baz"
}
""".data(using: .utf8)!
let decoder: JSONDecoder = JSONDecoder()
do {
let user: User = try decoder.decode(User.self, from: data)
print(user)
} catch {
print(error)
}