unicorn_surprise
unicorn_surprise

Reputation: 1109

Swift 4 Parsing an Object Array

I'm having problems transferring my parsing code over to Swift4/Xcode9. I'm parsing it through my model correctly and I know the problem is because I'm currently parsing through the root JSON object, however my REST API is structured JSON root -> data array -> further objects. I know it's probably simple but I've been struggling for ages. I have attached an image of the layout of my REST API, and just need to know how to step into objects to retrieve values. enter image description here

    let jsonUrlString = "HIDDEN"
        guard let url = URL(string: jsonUrlString) else
            {return}

        URLSession.shared.dataTask(with: url) { (data, response, err) in

            guard let data = data else {return}

            do {

                 let show =  try
                    JSONDecoder().decode(TvHeaderModel.self, from: data)
                print(show.title)

            } catch let jsonErr {
                print("Error serializing JSON", jsonErr)
            }

        }.resume()

    struct TvHeaderModel: Decodable    {
    var id: Int?
    var title: String?
    var year: Int?
    var songCount: Int?
    var poster: String?

    init(json: [String: Any])   {
        id = json["_id"] as? Int ?? -1
        title = json["title"] as? String ?? ""
        year = json["year"] as? Int ?? -1
        songCount = json["song_count"] as? Int ?? -1
        poster = json["poster_urL"] as? String ?? ""

    }
}

Upvotes: 0

Views: 1176

Answers (1)

vadian
vadian

Reputation: 285069

Basically you don't need the init(json initializer when using JSONDecoder and declaring all properties as optional and assigning always a non-optional value is nonsensical anyway.


To decode also the seasons add a struct

struct Season : Decodable {
        private enum CodingKeys : String, CodingKey {
            case id = "_id", season
            case show = "tv_show", createdDate = "created_at"
            case numberOfEpisodes = "episodes_count", numberOfSongs = "songs_count"
        }

        let id, season, show, numberOfEpisodes, numberOfSongs : Int
        let createdDate : Date
}

In TvHeaderModel add a property

let seasons : [Season]

And set the dateDecodingStrategy of the decoder to decode ISO8601 dates.

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
decoder.decode(TvHeaderModel.self, from: data)

Upvotes: 1

Related Questions