Home > Net >  How to create a struct model from a complex JSON response
How to create a struct model from a complex JSON response

Time:01-06

I am trying to consume data from an api in swift, json data has successfully been delivered back to the app but the json response from my backend is very complex hence forming struct for my model is very difficult. I'm able to only retrieve the simple strings but if I add the objects and arrays everything stops working

[
    {
        "type": "movie",
        "id": "ffff-ddd968-4cf0-a939-8skeu",
        "title": "Sorority Row",
        "description": "When five laldkdk",
        "categories": [],
        "genres": [
            "Mystery",
            "Horror"
        ],
        "links": {
            "amazonPrime": [
                {
                    "link": "somelink",
                    "format": "native_ios"
                },
                {
                    "link": "somelink",
                    "format": "native_ios"
                }
            ],
            "appleTvPlus": [],
            "disneyPlus": []
            "iTunes": [
                {
                    "link": "www.somelink",
                    "format": "webview_computer"
                }
            ],
            "netflix": [],
            "youTubePremium": []
        },
        "promoted": false,
        "certification": "18",
        "releaseDate": "2009-09-09",
        "runTime": 101,
        "userRating": null,
        "inUserList": false,
        "packShot": {
            "thumbnail": "imageurl"
        },
        "backdrop": {
            "thumbnail": "imageurl"
        }
    }
   ]
    
    struct Responder: Codable {
    let type: String
    let id: String
    let description: String
    let title: String
    let promoted: Bool
    let certification: String
    let firstAirDate: String
    let lastAirDate: String
    let numberEpisodes: Int
    let numberSeasons: Int
    let userRating: Int?
    let inUserList: Bool
    let thumbnail: PackShotObj
    let amazonPrime: linksObj
}

struct PackShotObj: Codable {
    let packShot: [String]
}

struct linksObj: Codable {
    let link: String
    let format: String
}

struct genres: Codable {
    let empty: String
}

CodePudding user response:

Here is the code that works, decoding your json data. Note the differences between my struct models and yours. You will need to consult the docs of the server to determine which fields are optionals and adjust the code for that:

struct ContentView: View {
    @State var responders: [Responder] = []
    
    var body: some View {
        List(responders) { responder in
            Text(responder.title)
            Text(responder.description)
            Text(responder.releaseDate)
        }
        .onAppear {
            let json = """
[
    {
        "type": "movie",
        "id": "ffff-ddd968-4cf0-a939-8skeu",
        "title": "Sorority Row",
        "description": "When five laldkdk",
        "categories": [],
        "genres": [
            "Mystery",
            "Horror"
        ],
        "links": {
            "amazonPrime": [
                {
                    "link": "somelink",
                    "format": "native_ios"
                },
                {
                    "link": "somelink",
                    "format": "native_ios"
                }
            ],
            "appleTvPlus": [],
            "disneyPlus": [],
            "iTunes": [
                {
                    "link": "www.somelink",
                    "format": "webview_computer"
                }
            ],
            "netflix": [],
            "youTubePremium": []
        },
        "promoted": false,
        "certification": "18",
        "releaseDate": "2009-09-09",
        "runTime": 101,
        "userRating": null,
        "inUserList": false,
        "packShot": {
            "thumbnail": "imageurl"
        },
        "backdrop": {
            "thumbnail": "imageurl"
        }
    }
   ]
"""
            // simulated API data
            let data = json.data(using: .utf8)!
            do {
                self.responders = try JSONDecoder().decode([Responder].self, from: data)
                print("\n---> responders: \n \(responders)\n")
            } catch {
                print("\n---> decoding error: \n \(error)\n")
            }
        }
    }
}

// MARK: - Responder
struct Responder: Identifiable, Codable {
    let type, id, title, description: String
    let categories: [String]
    let genres: [String]
    let links: Links
    let promoted: Bool
    let certification, releaseDate: String
    let runTime: Int
    let userRating: Int?
    let inUserList: Bool
    let packShot, backdrop: Backdrop
}

// MARK: - Backdrop
struct Backdrop: Codable {
    let thumbnail: String
}

// MARK: - Links
struct Links: Codable {
    let amazonPrime: [Provider]
    let appleTvPlus: [Provider]
    let disneyPlus: [Provider]
    let iTunes: [Provider]
    let netflix: [Provider]
    let youTubePremium: [Provider]
}

struct Provider: Codable {
    let link, format: String
}

CodePudding user response:

Just copy and paste this model to file and you are good to go.

struct Responder: Codable {
    let type, id, title, welcomeDescription: String
    let categories: [String]
    let genres: [String]
    let links: Links
    let promoted: Bool
    let certification, releaseDate: String
    let runTime: Int
    let userRating: Any?
    let inUserList: Bool
    let packShot, backdrop: Backdrop

    enum CodingKeys: String, CodingKey {
        case type, id, title
        case welcomeDescription = "description"
        case categories, genres, links, promoted, certification, releaseDate, runTime, userRating, inUserList, packShot, backdrop
    }
}

// MARK: - Backdrop
struct Backdrop: Codable {
    let thumbnail: String
}

// MARK: - Links
struct Links: Codable {
    let amazonPrime: [AmazonPrime]
    let appleTvPlus, disneyPlus: [String]
    let iTunes: [AmazonPrime]
    let netflix, youTubePremium: [String]
}

// MARK: - AmazonPrime
struct AmazonPrime: Codable {
    let link, format: String
}
  • Related