CoreData: prepare for segue NSManagedObject issue in Swift 3

398 views Asked by At

I am a beginner student in Swift 3 and I am currently studying CoreData. I am trying to do an App where I have a first controller that is a list view (tableviewcontroller) where I can see some students. Inside each cell, I have an image (UIImage) and 4 labels (Strings: name, preceptor, note and date) who fetch data from an Array that keeps the information from the entity "AlunosLista", who has one attribute for each item (image is binary data). I can add these information through another view controller (AddDataVC.swift) and list them perfectly. The app until here is fine. What i cannot do, and i have been trying a lot of things, many things, is to send the data from the row selected (clicked) to another viewcontroller for the detailed view (DetailsVC.swift). When i was using a simple Array, without CoreData, worked fine. But now i cannot do it. Now parts of the code:

File (1): TableviewController

 class TabelaListagem: UITableViewController {....

import CoreData
import UIKit

var alunos: [NSManagedObject?] = []
var gerenciadorDeDados: NSManagedObjectContext? = nil

override func viewDidLoad() {
    super.viewDidLoad()



//CORE DATA
    let AppleObject = UIApplication.shared.delegate as! AppDelegate
    gerenciadorDeDados = AppleObject.persistentContainer.viewContext

LoadFetch()
}

(.......)
 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let path = alunos[indexPath.row]
    let cell = tableView.dequeueReusableCell(withIdentifier: "celulaReuso", for: indexPath) as! ListagemCelulas
cell.lblAluno.text = path?.value(forKey: "nome") as? String
cell.lblPreceptor.text = path?.value(forKey: "preceptor") as? String
cell.lblData.text = path?.value(forKey: "dataHoje") as? String
cell.lblNotaAluno.text = path?.value(forKey: "nota") as? String
let caminhodaImagem = path?.value(forKey: "fotoAluno")
cell.imgAluno.image = UIImage(data: (caminhodaImagem as? NSData) as! Data)

return cell
}

Here should place the prepare(for segue), that I have tried many ways. This was the last one, who didn't worked too. "Build succeeded", but crashed.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueAluno" {
    if let pathC = tableView.indexPathForSelectedRow{
        let VCDestino = segue.destination as? DescriAluno
        let objeto = FecthResultado?.object(at: pathC)
        VCDestino?.alunoD = objeto as! NSManagedObject?
}

 }
}

File (2) DetailViewController

import UIKit
import CoreData
class DescriAluno: UIViewController {

@IBOutlet weak var imgFotoAluno: UIImageView!
@IBOutlet weak var nomeAluno: UILabel
@IBOutlet weak var txtPreceptor: UILabel!
@IBOutlet weak var txtNotaAluno: UILabel!
@IBOutlet weak var txtDataHoje: UILabel!

var gerenciadorDeDados: NSManagedObjectContext!
var alunoD: NSManagedObject?

override func viewDidLoad() {

super.viewDidLoad()

//CORE DATA
let AppleObject = UIApplication.shared.delegate as! AppDelegate
gerenciadorDeDados = AppleObject.persistentContainer.viewContext

imgFotoAluno.image = alunoD?.value(forKey: "fotoAluno")
    nomeAluno.text = alunoD?.value(forKey: "nome")
    txtPreceptor.text = alunoD?.value(forKey: "preceptor")
    txtNotaAluno.text = alunoD?.value(forKey: "nota")
    txtDataHoje.text = alunoD?.value(forKey: "dataHoje")
}

Error message after crash:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: is not a valid NSFetchRequest.'

I really don't know how to proceed. I have tried so many things, some of them told about NSFetchedResults, but i could write or understand them. If any one could help here, I appreciate. Thank you.

This is the Fetch request (func):

Ok. This is my fetch request:

func LoadFecth() {

    let ordenacaoAZ = NSSortDescriptor(key: "nome", ascending: true)
    let ordenacaoAZPrecep = NSSortDescriptor(key: "preceptor", ascending: true)
    let recupoerardados = NSFetchRequest<NSFetchRequestResult>(entityName: "AlunosLista")
    recupoerardados.sortDescriptors = [ordenacaoAZPrecep, ordenacaoAZ]

    do{

    let recupera = try gerenciadorDeDados?.fetch(recupoerardados)
        self.alunos = recupera as! [NSManagedObject]
        self.tableView.reloadData()
    }catch let erro as NSError{
        print("Erro ao carregar: \(erro.description)")
    }
}
1

There are 1 answers

4
jrturton On

Your core data life will get easier in every way if you use NSManagedObject subclasses for your entities. This allows you to use convenience accessors to get typed fetch requests and to skip all this value(forKey: stuff and use properties.

The error is that your fetch request is not valid.

You may have mistyped the entity name ("AlunosLista").

It may be getting upset because the type of the fetch request, without a specific NSManagedObject subclass, is actually NSFetchRequest<NSManagedObject>.

The best thing to do is enter a subclass for the entity in the model editor, generate the subclass files, then use this:

let recupoerardados: NSFetchRequest<AlunosLista> = AlunosLista.fetchRequest()