2

I get from a Rest API a result in json format. Now I wanna parse this JSON with the JSONDecoder but I don't really understand the structure of my response.

For that I already tried to create structs to get the "name" of "FirstUser".

{  
   "User":[  
      {  
         "FirstUser":{  
            "name":"John"
         },
         "Information":"XY",
         "SecondUser":{  
            "name":"Tom"
         }
1
  • 2
    This app.quicktype.io will help you to parse any JSON and let you know how to make your struct. Commented Jun 23, 2019 at 11:41

2 Answers 2

2

Json

{
    "User":[
      {
        "FirstUser":{
        "name":"John"
        },
       "Information":"XY",
        "SecondUser":{
        "name":"Tom"
      }
     }
   ]
}

Model

// MARK: - Empty
struct Root: Codable {
    let user: [User]

    enum CodingKeys: String, CodingKey {
        case user = "User"
    }
}

// MARK: - User
struct User: Codable {
    let firstUser: FirstUserClass
    let information: String
    let secondUser: FirstUserClass

    enum CodingKeys: String, CodingKey {
        case firstUser = "FirstUser"
        case information = "Information"
        case secondUser = "SecondUser"
    }
}

// MARK: - FirstUserClass
struct FirstUserClass: Codable {
    let name: String
}

Parse

do {
    let res = try JSONDecoder().decode(Root.self, from: data) 
    print(res.first?.firstUser.name)
} catch {
    print(error)
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer it works. Can you please explain me what you exactly have done. I wanna understand it.
-1

If I create model using previous json Using this link [blog]: http://www.jsoncafe.com to generate Codable structure or Any Format

Model

import Foundation
struct RootClass : Codable {
    let user : [Users]?
    enum CodingKeys: String, CodingKey {
        case user = "User"
    }

    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        user = try? values?.decodeIfPresent([Users].self, forKey: .user)
    }
}

struct Users : Codable {
    let firstUser : FirstUser?
    let information : String?
    let secondUser : SecondUser?
    enum CodingKeys: String, CodingKey {
        case firstUser = "FirstUser"
        case information = "Information"
        case secondUser = "SecondUser"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        firstUser = try? FirstUser(from: decoder)
        information = try? values?.decodeIfPresent(String.self, forKey: .information)
        secondUser = try? SecondUser(from: decoder)
    }
}
struct SecondUser : Codable {
    let name : String?
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        name = try? values?.decodeIfPresent(String.self, forKey: .name)
    }
}
struct FirstUser : Codable {
    let name : String?
    enum CodingKeys: String, CodingKey {
        case name = "name"
    }
    init(from decoder: Decoder) throws {
        let values = try? decoder.container(keyedBy: CodingKeys.self)
        name = try? values?.decodeIfPresent(String.self, forKey: .name)
    }
}

Parse

    do {
        let res = try JSONDecoder().decode(RootClass.self, from: data)
        print(res?.user?.first?.firstUser?.name ?? "Yours optional value")
    } catch {
        print(error)
    }

1 Comment

All those try? statements and the catch block in the Parse part make no sense. An optional plus decodeIfPresent plus try? is twice redundant. And also the suggested code generator creates pretty bad code.

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.