Swift3 CoreData - fetchResultsController

Me sale este error: ItinerariesCodeChallenge [2594: 1022206] *** Finalización de la aplicación debido a la excepción no detectada 'NSInvalidArgumentException', razón: 'Una instancia de NSFetchedResultsController requiere una solicitud de búsqueda con descriptores de clasificación Aquí está mi código. Realmente aprecio tu ayuda, lo he intentado todo durante días ...

import UIKit
import CoreData

class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {


    // outlets & properties:

    @IBOutlet weak var tableView: UITableView!

   var controller: NSFetchedResultsController<Itineraries>!


    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self


    }

    override func viewWillAppear(_ animated: Bool) {
        attemptFetch()
        tableView.reloadData()

    }



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

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CellContent

        configureCell(cell: cell, indexPath: indexPath as NSIndexPath)

        return cell


    }

    func configureCell(cell: CellContent, indexPath: NSIndexPath) {
        let itinerary = controller.object(at: indexPath as IndexPath)
        cell.configureCell(itineraries: itinerary)

    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let objs = controller.fetchedObjects, objs.count > 0 {
            let itinerary = objs[indexPath.row]
            performSegue(withIdentifier: "toDetailsVC", sender: itinerary)
        }
    }



    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "toDetailsVC" {
            if let destination = segue.destination as? DetailVC {
                if let itinerary = sender as? Itineraries {
                    destination.itineraryToEdit = itinerary
                }
            }
        }
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if let sections = controller.sections {

            let sectionInfo = sections[section]
            return sectionInfo.numberOfObjects

        }
        return 0
    }

    func numberOfSections(in tableView: UITableView) -> Int {

        if let sections = controller.sections {
            return sections.count
        }
        return 0
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 140
    }

    func attemptFetch() {

        let fetchRequest: NSFetchRequest<Itineraries> = Itineraries.fetchRequest()

        let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

        controller.delegate = self

        self.controller = controller

        do {

            try controller.performFetch()

        } catch {

            let error = error as NSError
            print("\(error)")
        }


    }


    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        switch(type) {

        case.insert:
            if let indexPath = newIndexPath {
                tableView.insertRows(at: [indexPath], with: .fade)
            }
            break

        case.delete:
            if let indexPath = indexPath {
                tableView.deleteRows(at: [indexPath], with: .fade)
            }
            break

        case.update:
            if let indexPath = indexPath {
                let cell = tableView.cellForRow(at: indexPath) as! CellContent
                configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
            }
            break

        case.move:
            if let indexPath = indexPath {
                tableView.deleteRows(at: [indexPath], with: .fade)
            }
            if let indexPath = newIndexPath {
                tableView.insertRows(at: [indexPath], with: .fade)
            }
            break

        }

Respuestas a la pregunta(1)

Su respuesta a la pregunta