Home > Back-end >  Swift Image conversion failed from one view controller to another controller
Swift Image conversion failed from one view controller to another controller

Time:02-16

I am trying to send the data in including image from one view controller to another . The data is fetching from API . The data is successfully loaded into first view controller including image but when I try to reuse same code with didSelectRow function I am getting following errors . Cannot assign value of type 'Data?' to type 'UIImage' . The error on this line dc.imagemovie = presenter.getImageData(by: row). Here is the code to fetch the data from API.

class MoviePresenter: MoviePresenterProtocol {
    
    private let view: MovieViewProtocol
    private let networkManager: NetworkManager
    private var movies = [Movie]()
    private var cache = [Int: Data]()
    var rows: Int {
        return movies.count
    }
    
    init(view: MovieViewProtocol, networkManager: NetworkManager = NetworkManager()) {
        self.view = view
        self.networkManager = networkManager
    }
    
    
    func getMovies() {
        let url = "https://api.themoviedb.org/3/movie/popular?language=en-US&page=3&api_key=6622998c4ceac172a976a1136b204df4"
        
        networkManager.getMovies(from: url) { [weak self] result in
            switch result {
            case .success(let response):
                self?.movies = response.results
                self?.downloadImages()
                DispatchQueue.main.async {
                    self?.view.resfreshTableView()
                }
            case .failure(let error):
                
                DispatchQueue.main.async {
                    self?.view.displayError(error.localizedDescription)
                }
            }
        }
    }
    
    func getTitle(by row: Int) -> String? {
        return movies[row].originalTitle
    }
    
    func getOverview(by row: Int) -> String? {
        return movies[row].overview
    }
    
    func getImageData(by row: Int) -> Data? {
        return cache[row]
    }
    
    private func downloadImages() {
        let baseImageURL = "https://image.tmdb.org/t/p/w500"
        let posterArray = movies.map { "\(baseImageURL)\($0.posterPath)" }
        
        let group = DispatchGroup()
        group.enter()
        for (index, url) in posterArray.enumerated() {
            networkManager.getImageData(from: url) { [weak self] data in
                if let data = data {
                    self?.cache[index] = data
                }
            }
        }
        group.leave()
        group.notify(queue: .main) { [weak self] in
            self?.view.resfreshTableView()
        }
    }
     
    
}

Here is the code in view controller to display the data into table view cell .

class MovieViewController: UIViewController {
    
    
    @IBOutlet weak var userName: UILabel!
    @IBOutlet weak var tableView: UITableView!
    
    private var presenter: MoviePresenter!
    
    var finalname = ""
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        userName.text = "Hello: "   finalname
        setUpUI()
        
       // configure presenter
       presenter = MoviePresenter(view: self)
        presenter.getMovies()
    }
    private func setUpUI() {
        tableView.dataSource = self
        tableView.delegate = self
    }
    
    
    @IBAction func selectSegment(_ sender: UISegmentedControl) {
        
        if sender.selectedSegmentIndex == 0{
        setUpUI()
        presenter = MoviePresenter(view: self)
        presenter.getMovies()
        }
    }
    
}

extension MovieViewController: MovieViewProtocol {
    
    func resfreshTableView() {
        tableView.reloadData()
    }
    
    func displayError(_ message: String) {
        let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
        let doneButton = UIAlertAction(title: "Done", style: .default, handler: nil)
        alert.addAction(doneButton)
        present(alert, animated: true, completion: nil)
    }
    
}

extension MovieViewController: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        presenter.rows
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: MovieViewCell.identifier, for: indexPath) as! MovieViewCell
        
        let row = indexPath.row
        let title = presenter.getTitle(by: row)
        let overview = presenter.getOverview(by: row)
        let data = presenter.getImageData(by: row)
        cell.configureCell(title: title, overview: overview, data: data)
        return cell
    }
    
   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let dc = storyboard?.instantiateViewController(withIdentifier: "MovieDeatilsViewController") as! MovieDeatilsViewController
        
        let row = indexPath.row
       dc.titlemovie = presenter.getTitle(by: row) ?? ""
       dc.overview = presenter.getOverview(by: row) ?? ""
       **dc.imagemovie = presenter.getImageData(by: row) // Error on this line** 
      
        self.navigationController?.pushViewController(dc, animated: true)
   }
    
    
}
/*
 var titlemoview = ""
 var overview = ""
 var imagemovie = UIImage()
 */

extension MovieViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
}

Here is the code for display the data .

class MovieDeatilsViewController: UIViewController {
    
    
    @IBOutlet weak var movieImage: UIImageView!
    
    @IBOutlet weak var movieTitle: UILabel!
    
    @IBOutlet weak var movieOverview: UILabel!
    
    
    var titlemovie = ""
    var overview = ""
    var imagemovie = UIImage()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        movieTitle.text = titlemovie
        movieOverview.text = overview
        movieImage.image = imagemovie
        
    }

}





 

CodePudding user response:

Get UIImage from data in configureCell(:, : , :) function by UIImage(data:yourdata) and assign to your imageview

let image =  UIImage(data:yourdata)
imageview.image = image
  • Related