TMDb api call - Swift

Viewed 1334

I'm calling the TMDb Api to get an array of movies by genre. I'm getting 'nil' back on many of the properties I want to access such as "vote_count", "poster_path" and "vote_average".

If I call the api in a browser I get all of the properties as expected.

Here's my model:

import Foundation

// MARK: - MovieList
struct MovieList: Codable {
    let page: Int
    let totalResults: Int?
    let totalPages: Int?
    let results: [Result]

    enum CodingKeys: String, CodingKey {
        case page
        case totalResults = "total_results"
        case totalPages = "total_pages"
        case results
    }
}

// MARK: - Result
struct Result: Codable {
    let popularity: Double?
    let voteCount: Int?
    let video: Bool?
    let posterPath: String?
    let id: Int?
    let adult: Bool?
    let backdropPath: String?
    let originalLanguage: OriginalLanguage?
    let originalTitle: String?
    let genreIDS: [Int]?
    let title: String?
    let voteAverage: Double?
    let overview, releaseDate: String?

    enum CodingKeys: String, CodingKey {
        case popularity
        case voteCount = "vote_count"
        case video
        case posterPath = "poster_path"
        case id, adult
        case backdropPath = "backdrop_path"
        case originalLanguage = "original_language"
        case originalTitle = "original_title"
        case genreIDS = "genre_ids"
        case title
        case voteAverage = "vote_average"
        case overview
        case releaseDate = "release_date"
    }
}

enum OriginalLanguage: String, Codable {
    case en = "en"
    case es = "es"
}

Here's the networking call:

func getMovieDetails(movie: Int, completion: @escaping (Result?) -> ()) {

        guard let url = URL(string: "https://api.themoviedb.org/3/movie/157336?api_key=6228bff945f7bd2m18c04fc3839829c0") else {
            fatalError("Invalid URL")
        }

            let config = URLSessionConfiguration.default
            let session = URLSession(configuration: config)

            let task = session.dataTask(with: url) { data, response, error in

                // Check for errors
                guard error == nil else {
                    print ("error: \(error!)")
                    return
                }
                // Check that data has been returned
                guard let data = data else {
                    print("No data")
                    return
                }

                do {

                    let decoder = JSONDecoder()
                    decoder.keyDecodingStrategy = .convertFromSnakeCase
                    let movieDetails = try decoder.decode(Result.self, from: data)

                    DispatchQueue.main.async {

                       completion(movieDetails)
                        print(movieDetails)

                    }

                } catch let err {
                    print("Err", err)
                }
            }
            // execute the HTTP request
            task.resume()
        }
    }

And here is the response:

MovieList(page: 1, totalResults: nil, totalPages: nil, results: [QuickFlicks.Result(popularity: Optional(171.78), voteCount: nil, video: Optional(false), posterPath: nil, id: Optional(454626), adult: Optional(false), backdropPath: nil, originalLanguage: nil, originalTitle: nil, genreIDS: nil, title: Optional("Sonic the Hedgehog"), voteAverage: nil, overview: Optional("Based on the global blockbuster videogame franchise from Sega, Sonic the Hedgehog tells the story of the world’s speediest hedgehog as he embraces his new home on Earth. In this live-action adventure comedy, Sonic and his new best friend team up to defend the planet from the evil genius Dr. Robotnik and his plans for world domination."), releaseDate: nil)])

Any help would be appreciated. Thank you.

1 Answers

You are giving contradicting instructions to the decoder, first you have the CodingKeys enum that say for instance that the posterPath property should be read from the poster_path key but then you set keyDecodingStrategy = .convertFromSnakeCase which means that the decoder first translates the key poster_path to posterPath before trying to match the key to a property.

So either remove decoder.keyDecodingStrategy = .convertFromSnakeCase or remove the CodingKeys enum

Related