2017-06-25 38 views
0

我得到這個錯誤: ItinerariesCodeChallenge [2594:1022206] ***終止應用程序,由於未捕獲的異常'NSInvalidArgumentException',原因:'NSFetchedResultsController的實例需要一個帶有sort descriptorsHere我的代碼的獲取請求。真的很感謝你的幫助,我已經嘗試了一切,現在天...Swift3 CoreData - fetchResultsController

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

請仔細閱讀錯誤信息,它告訴究竟出了什麼問題

NSFetchedResultsController的一個實例都需要一個讀取請求用排序描述符

添加至少一個排序描述:

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

側面說明,沒有涉及到的問題:刪除所有類型轉換as NSIndexPath,他們是多餘的。