3

I have a JSON response that contains information about a user.

{
  "userId": "123456789",
  "email": "\"[email protected]",
  "firstName": "\"foo\"",
  "lastName": "\"bar\"",
  "name": "\"foo bar",
  "bio": "\"boo baz\"",
  "age": "42"
}

I'd like to create 2 models, User and Profile from the same JSON, with a single request.

I'd then like Profile to be a property on the User struct.

At the moment, my standard struct looks like this -

struct User: Codable, Equatable {
    var userId: String
    var email: String
    var firstName: String
    var lastName: String
    var name: String?
    var bio: String?
    var age: Int?
}

I would prefer however to do something like this -

struct User: Codable, Equatable {
    var userId: String
    var email: String
    var profile: UserProfile // I'd like to wrap the profile info up in this field
}

struct UserProfile: Codable, Equatable {
    var firstName: String
    var lastName: String
    var name: String?
    var bio: String?
    var age: Int?
}

As profile does not exist on the response, I do not understand how I can decode the rest of the response into it.

0

1 Answer 1

4

Firstly, you should consider making all of the fields on your model immutable.

It is good practice not to change your data, but create an updated copy.

However, this should work -

let json = Data("""
 {
   "userId": "123456789",
   "email": "[email protected]",
   "firstName": "foo",
   "lastName": "bar",
   "name": "foo bar",
   "bio": "boo baz",
   "age": 42
 }
""".utf8)

struct User: Codable, Equatable {
    let userId: String
    let email: String
    let profile: UserProfile

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        userId = try values.decode(String.self, forKey: .userId)
        email = try values.decode(String.self, forKey: .email)
        profile = try UserProfile(from: decoder)
    }

}

struct UserProfile: Codable, Equatable {
        let firstName: String
        let lastName: String
        let name: String?
        let bio: String?
        let age: Int?
}

var result = try! JSONDecoder().decode(User.self, from: json)
print(result.profile)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.