Reputation: 2800
Lets say I have a dictionary like this:
{"user_data":{"id":3,"name":"Damian D","email":"[email protected]"},"status":true}
How can I use Codable
protocol to decode just user_data
into such struct
:
struct User: Codable {
private enum CodingKeys: String, CodingKey {
case id
case username = "name"
case email
}
let id: Int
let username: String
let email: String
}
Do I need to convert this sub dictionary into Data, or is there a easier way?
Upvotes: 5
Views: 4985
Reputation: 596
If you create nested Coding Keys you will accomplish decoding the response using only one data model.
Given the following JSON response:
let data = """
{
"user_data": {
"id":3,
"name":"Damian D",
"email":"[email protected]"
},
"status":true
}
""".data(using: .utf8, allowLossyConversion: false)!
and the following data model:
public struct User: Decodable {
var id: Int
var name: String
var email: String
// MARK: - Codable
private enum RootCodingKeys: String, CodingKey {
case userData = "user_data"
enum NestedCodingKeys: String, CodingKey {
case id
case name
case email
}
}
required public init(from decoder: Decoder) throws {
let rootContainer = try decoder.container(keyedBy: RootCodingKeys.self)
let userDataContainer = try rootContainer.nestedContainer(keyedBy: RootCodingKeys.NestedCodingKeys.self, forKey: .userData)
self.id = try userDataContainer.decode(Int.self, forKey: .id)
self.name = try userDataContainer.decode(String.self, forKey: .name)
self.email = try userDataContainer.decode(String.self, forKey: .email)
}
}
You can decode your response into a single object:
let decoder = JSONDecoder()
let user = try? decoder.decode(User.self, from: data)
Upvotes: 14
Reputation: 4729
Create a new struct that has a userData
member of type User
.
struct Response: Codable {
private enum CodingKeys: String, CodingKey {
case userData = "user_data"
case status
}
let userData: User
let status: Bool
}
Upvotes: 2