Search code examples
iosswiftrealm

Error passing data to tableViewController


I have a problem. I'm making an app that consumes an API from themoviedb and saves the movies in the Realm. On the main screen I am using the CollectionViewController, and when I touch the movie it will go to details. However when it goes to details nothing appears and when I select another film it brings the previous film.

Home:

import UIKit
import RealmSwift

class HomeViewController: UIViewController,UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UISearchBarDelegate {


    @IBOutlet weak var searchbar: UISearchBar!
    @IBOutlet weak var ListOfMovies: UICollectionView!


    var movies : Results<Moviess>!
    let realm = try! Realm()
    var detailsMovies = Moviess()

    override func viewDidLoad() {
        super.viewDidLoad()
        print(Realm.Configuration.defaultConfiguration.fileURL!)
        ListOfMovies.delegate = self
        ListOfMovies.dataSource = self
        searchbar.delegate = self
        movies = realm.objects(Moviess.self)
        getRequest()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

    }

    func getObjects(filter: String) -> Results<Moviess>{
        movies = realm.objects(Moviess.self).filter("title CONTAINS[cd] %@",filter)
        return movies
    }


    func getRequest(){
        print(movies.count)
        if movies.count < 1 {
            RequestData.requisicao { (result) in
                   switch(result){
                   case .success(let detalhe):
                    self.ListOfMovies.reloadData()
                   print(detalhe)
                   case .failure(let error):
                       print(error)
                   }
               }
        }}

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return movies.count
      }

      func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listOfMovies", for: indexPath) as! HomeCollectionViewCell
        let infos = movies[indexPath.item]
        cell.configurationMovie(movie: infos)
        return cell
      }
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        detailsMovies = movies[indexPath.row]
    }


      func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
          return UIDevice.current.userInterfaceIdiom == .phone ? CGSize(width: collectionView.bounds.width/2-20, height: 200) : CGSize(width: collectionView.bounds.width/3-20, height: 250)
      }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        print(searchText)
        if !searchText.isEmpty{
            let filtro = getObjects(filter: searchText)
            print(filtro)
            ListOfMovies.reloadData()
        }else{
            movies = realm.objects(Moviess.self)
            ListOfMovies.reloadData()
        }
    }

     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         if(segue.identifier == "details")
               {
                 let viewController = segue.destination as! DetailViewController
                print(detailsMovies)
                 viewController.conta = detailsMovies 
               }

            }

         }

Details:

import UIKit
import RealmSwift

class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{

    var conta: Moviess!
    let realm = try! Realm()

    @IBOutlet var tableView: UITableView!
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self
        tableView.reloadData()

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return [conta].count
     }

     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "details", for: indexPath) as! DetailsTableViewCell


        let infos = [conta][indexPath.item]

        cell.prepare(movie: infos!)
        return cell
    }   

}

Moviess

import RealmSwift
import UIKit

class Moviess: Object{
 @objc dynamic var id = 0
 @objc dynamic var title = ""
 @objc dynamic var overview = ""
 @objc dynamic var poster = ""
 @objc dynamic var isFavorites = false

override class func primaryKey() -> String? {
    return "id"
}
convenience init (id: Int){
    self.init()
    self.id = id
}

override class func indexedProperties() -> [String] {
    return ["isFavorites"]
}

func insertMovieData(list: Moviess){
    do {
        let realm = try! Realm()
        try! realm.write({ () -> Void in
            realm.add(list)
        })
    } catch let error as NSError{
        print("insert error : \(error)")
    }
}

func togleFavorite(){
    try? realm?.write{
        isFavorites = !isFavorites
     }
  }
}

I have no idea where I might be giving this "bug". If someone can help and explain what is going on it will be very useful.


Solution

  • Your problem is that prepare(for:sender:) is called before collectionView(_:, didSelectItemAt:). prepare(for:sender:) should not rely on collectionView(_:, didSelectItemAt:).

    Your prepare(for:sender:) method should look like this:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard let cell = sender as? UICollectionViewCell,
            let indexPath = ListOfMovies.indexPath(for: cell) else { return }
    
        if (segue.identifier == "details") {
            let viewController = segue.destination as! DetailViewController
            viewController.conta = movies[indexPath.item]
        }
    }