我无法使用 Alamofire 从 api 获取数据

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

我正在尝试使用 tmdb API 制作一个类似 IMDb 的应用程序,我已经完成了应用程序的第一部分,但是我无法从 API 获取数据,我已经尝试了一天多,但我无法解决问题。

print(viewModel.movie?.results?[indexPath.item].originalTitle ?? "")
在 homeViewController 的 cellForItemAt 中 作为此代码的结果,originalTitle 应该被打印出来,但它没有打印出来。

我正在尝试通过观看此视频系列来制作此应用程序:https://www.youtube.com/playlist?list=PLnoj2maz_tTO1u-1BjKs3xrEzKc3Rmj_T

如果你想看github上的所有代码,项目的github链接:https://github.com/mertplt/Filmly

  • 网络助手
    import Foundation
    enum  HTTPMethods: String{
        case get = "GET"
        case post = "POST"
    }
    enum    ErrorTypes: String,Error{
        case invalidData = "Invalid data"
        case invalidURL = "Invalid url"
        case generalError = "An error happened"
    }
    
    
    class NetworkHelper{
        static let shared = NetworkHelper()
        
        private let baseURL = "https://api.themoviedb.org/3/"
        private let apiKey = "509ef93252a59761a3c353f9ea114de0"
        
        func requestUrl(url: String) -> String {
       return baseURL + url + "?api_key=\(apiKey)"
           
            
        }
        
        
    }
  • 网络管理员
    import Alamofire
    
    class NetworkManager {
        static let shared = NetworkManager()
        
        func request<T: Codable>(type: T.Type,
                                 url: String,
                                 method: HTTPMethod,
                                 completion: @escaping((Result<T, ErrorTypes>)->())) {
            AF.request(url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? " ", method: method).responseData { response in
                switch response.result {
                case .success(let data):
                    self.handleResponse(data: data) { response in
                        completion(response)
    
                    }
                case .failure(_):
                    completion(.failure(.generalError))
                }
            }
            
            
        }
        
        fileprivate func handleResponse<T: Codable>(data: Data,completion: @escaping((Result<T, ErrorTypes>)->())){
            do{
                let result = try JSONDecoder().decode(T.self, from: data)
                completion(.success(result))
            }
            catch{
                completion(.failure(.invalidData))
            }
        }
        
    }

  • 家庭帮手
    import Foundation
    
    enum HomeEndpoint: String {
        case popular = "movie/popular"
        
        var path: String {
            switch self{
            case.popular:
                return NetworkHelper.shared.requestUrl(url: HomeEndpoint.popular.rawValue)
    
            }
        }
    }

-HomeManager

import Foundation

protocol HomeManagerProtocol {
    func getCatagoryMovies(complete:@escaping((Movie?,Error?)->()))
}

class HomeManager{
    static let shared = HomeManager()
    
    func getCatagoryMovies(complete:@escaping((Movie?,Error?)->())){
        NetworkManager.shared.request(type: Movie.self,
                                      url: HomeEndpoint.popular.path,
                                      method:.get) { response in
            switch response{
            case .success(let data):
                complete(data,nil)
            case .failure(let error):
                complete(nil,error)
            }
        }
    }

}

-电影

import Foundation

// MARK: - Movie
struct Movie: Codable {
    let page: Int?
    let results: [MovieResult]?
    let totalPages, totalResults: Int?

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

// MARK: - MovieResult
struct MovieResult: Codable  {
    let adult: Bool?
    let backdropPath: String?
    let genreIDS: [Int]?
    let id: Int?
    let originalLanguage, originalTitle, overview: String?
    let popularity: Double?
    let posterPath, releaseDate, title: String?
    let video: Bool?
    let voteAverage: Double?
    let voteCount: Int?
    let character, creditID: String?
    let order: Int?
    let department, job: String?
}

-HomeViewModel

import Foundation


class HomeViewModel{
    let manager = HomeManager.shared
    
    var movie: Movie?
    var errorCallBack: ((String)->())?
    var successCallBack: (()->())?
    
    func getCatagoryItems(){
        manager.getCatagoryMovies { [weak self ]Movie, error in
            if let error = error{
                self?.errorCallBack?(error.localizedDescription)

            }else{
                self?.movie = Movie
                self?.successCallBack?()
            }
        }
    }
   
    
    func numberOfItems() -> Int{
        movie?.results?.count ?? 0
        
    }
}
 

-HomeViewController

import UIKit

class  HomeViewController: UIViewController {
    
    @IBOutlet private weak var collectionView: UICollectionView!
    let viewModel = HomeViewModel()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        collectionSetup()
        viewModelConfiguration()
        
        
    }
    
    fileprivate func collectionSetup(){
        collectionView.registerCell(type: VerticalCollectionViewCell.self)
    }
    
    fileprivate func viewModelConfiguration(){
        
        viewModel.getCatagoryItems()
        viewModel.errorCallBack = { [weak self] errorMesage in
            print("error: \(errorMesage)")
        }
        viewModel.successCallBack = { [weak self] in
            self?.collectionView.reloadData()
            
        }
    }


}
extension HomeViewController:UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return viewModel.numberOfItems()
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell: VerticalCollectionViewCell = collectionView.dequeueCell(for: indexPath)
        print(viewModel.movie?.results?[indexPath.item].originalTitle ?? "")
        cell.backgroundColor = .red
        return cell
        
    }
        
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width * 327 / 375, height: 120)
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
        CGSize(width: collectionView.frame.width, height: 365)

    }
    
    
}
ios swift uikit alamofire
© www.soinside.com 2019 - 2024. All rights reserved.