I am new to Swift
JSON
, so I am practicing in Swift Playgrounds
. I'm pretty sure that this would be considered decoding a nested JSON
key. But like I said, I'm new and I am not familiar with all of the technical terms.
Anyway, I thought that this code was right, but for some reason it won't print. And it's not showing me any error, which is making it harder to fix. But, I must be doing something wrong.
import UIKit
let jsonData :Data = """
{
"id": 1,
"name": "John Smith",
"username": "Johnny",
"email": "[email protected]",
"address": {
"street": "Some Street",
"suite": "100",
"city": "SomeCity",
"zipcode": "12345",
}
}
""".data(using: .utf8)!
struct User :Decodable {
let id :Int
let name :String
let userName :String
let email :String
let street :String
let suite :String
let city :String
let zipCode :String
private enum UserKeys :String, CodingKey {
case id
case name
case userName
case email
case address
}
private enum AddressKeys :String, CodingKey {
case street
case suite
case city
case zipCode
}
init(from decoder :Decoder) throws {
let userContainer = try decoder.container(keyedBy: UserKeys.self)
self.id = try userContainer.decode(Int.self, forKey: .id)
self.name = try userContainer.decode(String.self, forKey: .name)
self.userName = try userContainer.decode(String.self, forKey: .userName)
self.email = try userContainer.decode(String.self, forKey: .email)
let addressContainer = try userContainer.nestedContainer(keyedBy: AddressKeys.self, forKey: .address)
self.street = try addressContainer.decode(String.self, forKey: .street)
self.suite = try addressContainer.decode(String.self, forKey: .suite)
self.city = try addressContainer.decode(String.self, forKey: .city)
self.zipCode = try addressContainer.decode(String.self, forKey: .zipCode)
}
}
if let user = try? JSONDecoder().decode(User.self, from: jsonData) {
print(user.name)
print(user.city)
}
The userName
and zipCode
properties are camel-case as they should be following Swift
standards. However, as what often happens with JSON
data, the keys "username"
and "zipcode"
are both presented in lowercase. Fortunately, there is an easy fix for this. In your private enums
, simply set both of the properties
to their lowercase stringValue
like this:
case userName = "username"
case zipCode = "zipcode"
Technically, I think that your dealing with a nested dictionary
of JSON properties
. I'm not sure though, maybe some of the experts on this site can elaborate more on that.