core-data - Swift 3 核心数据 - 获取结果 Controller

标签 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

        }

最佳答案

请仔细阅读错误消息,它准确地说明了问题所在

An instance of NSFetchedResultsController requires a fetch request with sort descriptors.

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

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

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

关于core-data - Swift 3 核心数据 - 获取结果 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45489190/

相关文章:

iOS:NSPredicate for "@count == 0"用于一对一和一对多关系

iphone - 关系中的核心数据总和

ios - 由于未捕获的异常 'NSInternalInconsistencyException' 而终止应用程序,原因 : 'no object at index 3 in section at index 0'

iphone - 直接从 NSFetchedResultsController 获取

ios - 获取 NSArray 中 NSFetchRequest 的所有结果

ios - 从 Model.xcdatamodeld 获取所有实体

swift3 - 在 swift 3.0 中将坐标数组转换为 geojson 字符串

ios - 值类型设计模式取代类

ios - CLLocationManager() Location 在模拟器中为 nil

ios - 日期部分标题不起作用