首页 > 解决方案 > JSON解码不填充表视图

问题描述

我正在尝试从网站 movieDatabase.com 解析数据但是将数据解码为 json 并填充我的表格视图存在一些问题。我不确定为什么会发生这种情况。请帮助我找出问题所在。这是我的代码。https://github.com/lexypaul13/Movie-Browser/tree/main/Movie-Browser

struct Movies: Codable {
    let overview:String?
    let original_title: String?
    let poster_path:String
}


struct ApiResponse:Codable, Hashable {
    let page:Int
    let shows:[Movies]

    enum CodingKeys:String, CodingKey {
        case page = "page"
        case shows = "results"
    }
}



class NetworkManger{

    enum EndPoint{
        case showList
    }

    static let shared = NetworkManger()
    private let baseURL : String
    private var  apiKeyPathCompononent :String

    private init(){
        self.baseURL = "https://api.themoviedb.org/3/movie/now_playing?"
        self.apiKeyPathCompononent =  "api_key=a07e22bc18f5cb106bfe4cc1f83ad8ed"
    }
    private var jsonDecoder:JSONDecoder = {
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        return decoder
    }()



    func get<T:Decodable>(_ endPoints: EndPoint, urlString: String,  completed:@escaping(Result<T?,ErroMessage>)->Void){
        guard let url = urlBuilder(endPoint: endPoints) else {
            completed(.failure(.invalidURL))
            return
        }

        let task = URLSession.shared.dataTask(with: url){ data, response, error in
            if let _ = error {
                completed(.failure(.unableToComplete))
                return
            }

            guard let response = response as? HTTPURLResponse, response.statusCode==200 else {
                print(ErroMessage.invalidResponse.rawValue)
                completed(.failure(.invalidResponse))
                return
            }

            guard let data = data else{
                completed(.failure(.invalidData))
                return
            }
            do{
                let apiResponse = try self.jsonDecoder.decode([T].self, from: data)
                DispatchQueue.main.async {
                    completed(.success(apiResponse as? T))
                }

            } catch{
                print(ErroMessage.invalidData.rawValue)
            }
        }
        task.resume()
    }
    private func urlBuilder(endPoint:EndPoint )->URL?{
        switch endPoint {
        case .showList:
            return URL(string: baseURL + apiKeyPathCompononent )
        }
    }

    func getMovies(){
        NetworkManger.shared.get(.showList, urlString: "") { [weak self] (result: Result<[Movies]?,ErroMessage> ) in
            guard let self = self else { return }
            switch result{
            case .success(let movies):
                self.movies = movies ?? []
                DispatchQueue.main.async {self.tableView.reloadData()}

            case .failure(let error):
                print(error.localizedDescription)
            }

        }
    }
}

标签: iosswift

解决方案


The root object returned from the api is your ApiResult struct. This contains an array of movies (which you have mapped to the shows property of the ApiResult)

You need to change the getMovies function so that the right generic type can be inferred and the json decoder can do the right thing

func getMovies(){
        NetworkManger.shared.get(.showList, urlString: "") { [weak self] (result: Result<ApiResult,ErroMessage> ) in
            guard let self = self else { return }
            switch result{
            case .success(let apiResult):
                self.movies = apiResult.shows
                DispatchQueue.main.async {self.tableView.reloadData()}

            case .failure(let error):
                print(error.localizedDescription)
            }

        }
    } 

推荐阅读