对 Codable 感到困惑

问题描述 投票:0回答:1

我正在尝试使用电影数据库 API 获取电影数据并将其显示在表视图上,但我的代码实际上并未获取任何数据。

class MovieData: NSObject, Decodable {
    var movies: [Movie]?
    
    private enum CodingKeys: String, CodingKey {
        case movies = "results"
    }
}

我认为这与我的编码键有关,因为我要检索的电影数据位于数组内。 看到这里。但我对 Codable 的工作原理有点困惑。

class Movie: NSObject, Decodable {

    var title: String?
    var year: String?
    var rate: Double?
    var posterImage: String?
    var overview: String?
        
    private enum MovieKeys: String, CodingKey {
        case title
        case overview
        case releaseDate = "release_date"
        case rate = "vote_average"
        case posterImage = "poster_path"
    }
    
    required init(from decoder: Decoder) throws {
        let movieContainer = try decoder.container(keyedBy: MovieKeys.self)
        
        // Get movie info
        title = try movieContainer.decode(String.self, forKey: .title)
        overview = try movieContainer.decode(String.self, forKey: .overview)
        posterImage = try movieContainer.decode(String.self, forKey: .posterImage)
        rate = try movieContainer.decode(Double.self, forKey: .rate)
        // releaseDate = try movieContainer.decode(String.self, forKey: .releaseDate)
               
    }
}

这就是我用来进行 API 调用的方法,因此当用户加载到视图中时,API 将获取电影数据并将其显示在单元格上。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let requestURL = URL(string: "https://api.themoviedb.org/3/movie/popular?api_key=\(apiKey)&language=en-US&page=1")
        if let requestURL = requestURL {
            Task {
                
                do {
                    let (data, response) = try await URLSession.shared.data(from: requestURL)
                    guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                        throw MovieListError.invalidServerResponse
                    }
                    
                    let decoder = JSONDecoder()
                    let movie = try decoder.decode(Movie.self, from: data)
                    
                    print(data)
                    print(movie)
                }
                catch {
                    print(error)
                }
            }
        }  
    }
ios swift rest codable
1个回答
2
投票

您似乎正在尝试解码错误的对象。应该是

MovieData.self
而不是
Movie.self
。然后你可以迭代
Movie
的数组。

override func viewDidLoad() {
    super.viewDidLoad()
    
    let requestURL = URL(string: "https://api.themoviedb.org/3/movie/popular?api_key=\(apiKey)&language=en-US&page=1")
    if let requestURL = requestURL {
        Task {
            
            do {
                let (data, response) = try await URLSession.shared.data(from: requestURL)
                guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                    throw MovieListError.invalidServerResponse
                }
                
                let decoder = JSONDecoder()
                // change Movie.self to MovieData.self
                let movies = try decoder.decode(MovieData.self, from: data)
                
                print(data)
                print(movies)
            }
            catch {
                print(error)
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.