1

I've defined a custom data model for a User Object in Swift like so: user data model

I've got a function that pulls User data from an API like so: get data from api

Here's the response when calling the same endpoint with Postman: api response

And here's the console debug output from line 75 of my function, showing that I'm actually receiving that data: debug output

So that all looks good as far as I can tell. I'm then using JSONDecoder().decode to decode the jsonData I receive from the api, for which I'm not getting any errors. However, when I'm then printing a field from the returned user object, that field (as well as all others) are "nil": all fields in user object are nil

I'm sure it's something small and stupid but I've spent hours now and can't figure out what it is. Can anyone spot the error and let me know what I'm doing wrong here?

Help much appreciated!!!

Bernhard Engl
  • 243
  • 1
  • 2
  • 12
  • Please add the content in the links directly to your post. The post needs to be available for others in the future and links tend to go dead. – Marcy Dec 25 '19 at 15:53
  • Welcome to Stackoverflow. Please don't post images, post text. And you forgot to decode the root object of the JSON which contains keys like `statuscode`. – vadian Dec 25 '19 at 15:53

1 Answers1

3

For Codable you need to give same name of properties to the json key. And make sure it's in correct scope. For example you email properties inside of detailresponse json object & detailresponse inside of main json object. If you don't wont more class you need to use it's init container method.

class Response: Codable {
    var statuscode: Int?
    var response_type: Int?
    // Other properties
    var detailresponse: DetailResponse?
}

class DetailResponse: Codable {
    var id: Int?
    // Other properties
    var socialmediadata: User?
}

class User: Codable {
    var id: Int?
    var email: String?
    // Other properties
}

Now, json will parse like this.

let response = try JSONDecoder().decode(Response.self, from: jsonData)
print(response.detailresponse?.socialmediadata?.email ?? "")
  • I'd have 2 more questions, for which - if ok for you - I hope to be able leverage your knowledge and expertise: 1) Is there a way to get rid of the outer response structure? Don't really need it in my user object. In fact, I believe when I, later on, encode from that user object and send data back to the api, that wouldn't work, as it's expecting a user object, without the surrounding response structure 2) There are even more nested objects in the api response. Can I put the corresponding classes into separate files or will the decoder struggle with that? – Bernhard Engl Dec 26 '19 at 12:03
  • @BernhardEngl Yes you can create separate files for each class. If you need to send User object to backend api than you just need to encode User object. Also you can check [this](https://stackoverflow.com/q/44549310/10506289) it's help full to understand **Codable**. – Haresh Gediya Dec 27 '19 at 16:05
  • Thanks for your input!! My main problem with this overall structure is, that I'm unsure how I can keep the object carried in Response.detailresponse generic - i.e. detailresponse now hardwired to User structure but will carry other data structures for other responses. Is there an elegant way to solve that? class Response: Decodable { var statuscode: Int? // Other properties var detailresponse: User? } class User: Codable { var id: String? // Other properties } class SocialMediaData: Codable { var id: Int? // Other properties } – Bernhard Engl Dec 29 '19 at 09:17
  • Just realised it's getting a bit messy with commenting on this one. Created a fresh question for others to benefit as well: https://stackoverflow.com/questions/59518330/how-to-keep-a-flexible-structure-when-using-codable-in-swift – Bernhard Engl Dec 29 '19 at 09:49