Reputation: 1793
I am accessing an API and decoding the json response into a User object, but I am attempting to change the JSON API strcuture. If I return a basic JSON object using this code
let httpURL = "https://dev.test/api/user"
var request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data else {return}
do {
let user = try JSONDecoder().decode(User.self, from: data)
DispatchQueue.main.async {
print(user.email)
}
} catch let jsonErr {
print(jsonErr)
}
}
task.resume()
and the following JSON
{
"id": 2,
"email": "[email protected]",
}
This works fine, but I want to changed the API to return a set of nested objects. For example
{
"data": {
"user": {
"id": 2,
"email": "[email protected]"
},
"notifications": [
{
"id": "123",
"notifiable_type": "App\\User"
}
]
}
}
How can I decode the User? I've tried several variations of this let user = try JSONDecoder().decode(User.self, from: data.data.user)
and let user = try JSONDecoder().decode(User.self, from: data["data"]["user"])
bt
Upvotes: 0
Views: 275
Reputation: 100503
You can try
struct Root: Codable {
let data: DataClass
}
struct DataClass: Codable {
let user: User
let notifications: [Notification]
}
struct Notification: Codable {
let id, notifiableType: String
enum CodingKeys: String, CodingKey {
case id
case notifiableType = "notifiable_type"
}
}
struct User: Codable {
let id: Int
let email: String
}
let user = try JSONDecoder().decode(Root.self, from:data)
OR
do {
let con = try JSONSerialization.jsonObject(with:data, options: [:]) as! [String:Any]
let data = con["data"] as! [String:Any]
let user = data["user"] as! [String:Any]
let finData = try JSONSerialization.data(withJSONObject:user, options: [:])
let userCon = try JSONDecoder().decode(User.self, from:finData)
print(userCon)
}
catch {
print(error)
}
Upvotes: 2