Swift3 CoreData - fetchResultsController

时间:2017-06-25 17:42:27

标签: core-data swift3 nsfetchedresultscontroller

我收到此错误: ItinerariesCodeChallenge [2594:1022206] ***由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' NSFetchedResultsController的实例需要带有排序描述符的获取请求,这是我的代码。非常感谢您的帮助,我已经尝试了好几天......

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

        }

1 个答案:

答案 0 :(得分:1)

请仔细阅读错误消息,它确切地说明错误

  

NSFetchedResultsController的实例需要带有排序描述符的获取请求

添加至少一个排序描述符:

let fetchRequest: NSFetchRequest<Itineraries> = Itineraries.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "...")] 
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

附注,与问题无关:删除所有类型转换as NSIndexPath,它们是多余的。