Decoding Api Data

{
  "page": 1,
  "results": [
  {
  "poster_path": "/cezWGskPY5x7GaglTTRN4Fugfb8.jpg",
  "adult": false,
  "overview": "When an unexpected enemy emerges and threatens global safety and security, Nick Fury, director of the international peacekeeping agency known as S.H.I.E.L.D., finds himself in need of a team to pull the world back from the brink of disaster. Spanning the globe, a daring recruitment effort begins!",
  "release_date": "2012-04-25",
  "genre_ids": [
  878,
  28,
  12
  ],
  "id": 24428,
  "original_title": "The Avengers",
  "original_language": "en",
  "title": "The Avengers",
  "backdrop_path": "/hbn46fQaRmlpBuUrEiFqv0GDL6Y.jpg",
  "popularity": 7.353212,
  "vote_count": 8503,
  "video": false,
  "vote_average": 7.33
  },




  {
  "poster_path": "/7cJGRajXMU2aYdTbElIl6FtzOl2.jpg",
  "adult": false,
  "overview": "British Ministry agent John Steed, under direction from \"Mother\", investigates a diabolical plot by arch-villain Sir August de Wynter to rule the world with his weather control machine. Steed investigates the beautiful Doctor Mrs. Emma Peel, the only suspect, but simultaneously falls for her and joins forces with her to combat Sir August.",
  "release_date": "1998-08-13",
  "genre_ids": [
  53
  ],
  "id": 9320,
  "original_title": "The Avengers",
  "original_language": "en",
  "title": "The Avengers",
  "backdrop_path": "/8YW4rwWQgC2JRlBcpStMNUko13k.jpg",
  "popularity": 2.270454,
  "vote_count": 111,
  "video": false,
  "vote_average": 4.7
  }

]

}





Hi,


I have a small problem with decoding this Data. Can somebody please tell me how to decode this data. Thank you!


Best regards


Philip

Replies

I have a small problem with decoding this Data.


Please explain what is the problem and show what you have done till now.

struct MovieInfos: Codable {
    let results: [MovieInfo]
}

struct MovieInfo: Codable {
    var movieId: Int
    var title: String
    var profilImage: String
    var releaseDate: String
    var vote_average: Double
    var vote_count: Int
    var overview: String

    enum keys: String , CodingKey {
        case movieId = "id"
        case title
        case profilImage = "poster_path"
        case releaseDate = "release_date"
        case vote_average
        case vote_count
        case overview
    }

    init(from decoder: Decoder) throws {
        let valueContainer = try decoder.container(keyedBy: keys.self)

        self.movieId = try valueContainer.decode(Int.self, forKey: keys.movieId)
        self.title = try valueContainer.decode(String.self, forKey: keys.title)
        self.profilImage = try valueContainer.decode(String.self, forKey: keys.profilImage)
        self.releaseDate = try valueContainer.decode(String.self, forKey: keys.releaseDate)
        self.vote_average = try valueContainer.decode(Double.self, forKey: keys.vote_average)
        self.vote_count = try valueContainer.decode(Int.self, forKey: keys.vote_count)
        self.overview = try valueContainer.decode(String.self, forKey: keys.overview)
    }



}


struct MovieInfoController {
   
    func fetchMovieInfo(query: [String: String] ,completion: @escaping ([MovieInfo]?) -> Void)
    {
        let baseURL = URL(string: "https://api.themoviedb.org/3/search/movie")!

       
        guard let url = baseURL.withQueries(query) else {
            completion(nil)
            print("Unable to build url with queries")
            return
        }
       
       
        let task = URLSession.shared.dataTask(with: url) { (data,
            response, error) in
            let jsonDecoder = JSONDecoder()
            if let data = data {
               
                let string = String(data: data, encoding: .utf8)
                print(string!)
               
                do {
                    let response = try jsonDecoder.decode(MovieInfos.self, from: data)
                    completion(response.results)
                } catch {
                    print("**** doch nicht ab")
                }
               
            } else {
                print("Either no data was returned, or data was not serialized.")
                completion(nil)
                return
            }
        }
        task.resume()
    }
  


I am making a network request to get movies from the moviedatabase. The network request is working fine but decoding the data is not working fine. After the request I print all my data in the console. Normally all of the data should be decode in the MovieInfo struct but the function sometimes forgot to decode some movies. So decoding is working but sometimes it forgot to decode data from the request. For example: The network request give me five movies. All movies are print to the Console, so the network request is working correctly. But the decode function is not decoding all five movies in the MovieInfo Struct. What I m doing wrong? I hope you can understand my problem.

Thanks for updating. Your code would not work for some sort of data according to the API reference of the service and throw some decoding error.


So, please clarify:

the decode function is not decoding all five movies in the MovieInfo Struct

(Meaning, you have some partial result in `response`.)

or

the decode function is not decoding any five movies in the MovieInfo Struct

(Just **** doch nicht ab is shown.)

This is what happen.


the decode function is not decoding all five movies in the MovieInfo Struct

(Meaning, you have some partial result in `response`.)



Thank you !!

Thanks for your response. But it is the one I'm afraid of..., as I cannot reproduce the same behavior with some possible JSON data which the API doc is suggesting.


So, this may not be the reason of your issue, but I show you one thing you need to fix.


The API doc says poster_path and backdrop_path can be null. So your `profilImage` should be Optional.

You may need something like this:

struct MovieInfo: Codable {
    var movieId: Int
    var title: String
    var profilImage: String? //<-
    var releaseDate: String
    var vote_average: Double
    var vote_count: Int
    var overview: String
    
    enum CodingKeys: String , CodingKey {
        case movieId = "id"
        case title
        case profilImage = "poster_path"
        case releaseDate = "release_date"
        case vote_average
        case vote_count
        case overview
    }
}


I have tried the struct above (with Xcode 10.1) and works fine with some inputs I generated for testing.

Please try it and see what happens. And when you find a weird behavior, please show the JSON text shown by your `print(string!)`.

Thanks for helping me! I tried your Code but my problem is still there. Here is the Json text in print(string!). In this example the network request give me the movie "MEG" back. So I was searching for the movie. You can see in the json the results. As you can see the network request give me the right movie back. As I said, sometimes the jsondata is not decoding. Here the jsondata from the movie comes from the network request but the decoding is not working. As you can see the catch statement is printed to the console("**** doch nicht ab"). Here is the do-Catch function again from the top.


  1. do {
  2. let response = try jsonDecoder.decode(MovieInfos.self, from: data)
  3. completion(response.results)
  4. } catch {
  5. print("**** doch nicht ab")
  6. }





{"page":1,"total_results":936,"total_pages":47,"results":[{"vote_count":1436,"id":345940,"video":false,"vote_average":6,"title":"Meg","popularity":97.207,"poster_path":"\/emn6QmTTqsxmibjfJkxROL4Il7M.jpg","original_language":"en","original_title":"The Meg","genre_ids":[28,878,53],"backdrop_path":"\/rH79sB6Nkx4cMW3JzsUy7wK0rhX.jpg","adult":false,"overview":"Nachdem ein Tiefsee-U-Boot von einem ausgestorben geglaubten Riesenhai angegriffen wird, sinkt das Fahrzeug in den tiefsten Graben des Pazifik und liegt dort manövrierunfähig am Meeresgrund. Der Crew an Bord läuft allmählich die Zeit davon und daher engagiert der Meeresforscher Dr. Minway Zhang den erfahrenen Taucher Jonas Taylor. Taylor ist zwar Experte für Bergungen in der Tiefsee, allerdings ist er vor Jahren schon einmal mit dem urzeitlichen Riesenhai, einem mehr als 20 Meter langen Megalodon, aneinandergeraten. Doch gemeinsam mit Dr. Zhangs Tochter Suyin muss er nun seine Ängste überwinden und schwere Geschütze auffahren, um den eingeschlossenen Menschen zur Hilfe eilen zu können und die Weltmeere von der Schreckensherrschaft des Urzeitmonsters zu befreien…","release_date":"2018-08-09"},{"vote_count":80,"id":62564,"video":false,"vote_average":6.2,"title":"Turn Me On","popularity":5.916,"poster_path":"\/mqgW1aXQc0Exj3qyphUoSvhBch0.jpg","original_language":"no","original_title":"Få meg på, for faen","genre_ids":[18,35],"backdrop_path":"\/xH6V1gnF8kZwOmczwmflTpF9TxC.jpg","adult":false,"overview":"Alma denkt nur an das Eine – ja, ***! Aber was soll man auch sonst groß machen in diesem lausigen Kaff namens Skoddeheimen? Almas beste Freundin Sara verfasst entflammte Briefe an Straftäter in amerikanischen Gefängnissen, um ihrem Verlangen nach menschlicher Nähe Ausdruck zu geben. Alma hingegen sucht sich Objekte ihres Begehrens lieber in der Nachbarschaft. Praktisch jeder und jede käme für Alma in Frage – und wenn die Erregung Überhand nimmt, gibt es ja noch Stig, den jungen Mann bei der ***-Hotline, der ihr hilft, sich Befriedigung zu verschaffen. Almas stärkste Sehnsucht aber gilt Artur, dem spröden Nachbarjungen. Als der jedoch ihren Avancen höchst tölpelhaft begegnet, gerät Alma in einen skandalös schlechten Ruf.","release_date":"2011-08-19"}..................]}


**** doch nicht ab

Unfortunately, the JSON you have shown is succesfully parsed with my code above.


But, when you see **** doch nicht ab, it might be far easier than seeing partial result.

What do you get if you change the line of `print` to `print("**** doch nicht ab", error)` ?

Okay the printed error show me this when I change the print line : "The data couldn’t be read because it is missing".

But I dont understand this error because I m getting back the movie "MEG" as you can see in the json. So why it is missing???

Thanks for helping!!!

It is not the behavior I can see using `print(error)`. Please confirm you exactly followed my suggestion,

The line is really `print("**** doch nicht ab", error)`?


`print(error.localizedDescription)` or using debugger does not give you enough info.

Oh I m sorry, I missunderstand you. The error show me this in the console:


**** doch nicht ab valueNotFound(Swift.String, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 18", intValue: 18), keys(stringValue: "poster_path", intValue: nil)], debugDescription: "Expected String value but found null instead.", underlyingError: nil))

The error message is clear enough, there exists a value null for key `"poster_path"`. And I cannot reproduce the same issue with some hand generated JSON data with value null for key `"poster_path"`, when using my struct MovieInfo.

I dont understand it. Where is the issue? In my code or in the network request?

In my code or in the network request?


In YOUR code.