Search code examples
swiftcore-datansfetchedresultscontroller

Instantiating NSFetchedResultsController terminating with uncaught exception


I am instantiating a NSFetchedResultsController with a fetchRequest of an abstract class:

private func setupFetchController() {
    let fetchRequest : NSFetchRequest<NSFetchRequestResult> = SearchEntity.fetchRequest()
    let fetchController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    self.fetchController = fetchController
}

The SearchEntity is an abstract parent class of Person and Group. I used this to be able to fetch 2 entities with 1 NSFetchedResultsController. However the app crashes when this function is called:

libc++abi.dylib: terminating with uncaught exception of type NSException

I have narrowed it down to uncommenting and commenting the creation of the NSFetchedResultsController. I have 2 more of these functions with exactly the same style which work.

What am I doing/is going wrong?

edit: to Add to this. I am able to manually fetch the SearchEntity by just using context.performFetch(...) which gives me correct results. However, hence the name, I'm going to search it so I need to be able to update efficiently.

edit2:

Example of same function elsewhere that is functioning:

private func setupFetchController() {
    let fetchRequest : NSFetchRequest<NSFetchRequestResult> = Person.fetchRequest()

    // Sort Persons
    let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true)
    let sortDescriptor2 = NSSortDescriptor(key: "lastName", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor, sortDescriptor2]

    // Filter Persons (only iType = 1)
    let predicate = NSPredicate(format: "iType == %i", 1)
    fetchRequest.predicate = predicate

    // Create the FetchController
    let fetchController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "sectionName", cacheName: nil)
    self.fetchController = fetchController
}

Solution

  • You get the exception because at least one sort descriptor is required.

    From the documentation:

    You typically create an instance of NSFetchedResultsController as an instance variable of a table view controller. When you initialize the fetch results controller, you provide four parameters:

    1) A fetch request. This must contain at least one sort descriptor to order the results.

    2) A managed object context. The controller uses this context to execute the fetch request.

    3) Optionally, a key path on result objects that returns the section name. The controller uses the key path to split the results into sections (passing nil indicates that the controller should generate a single section).

    4) Optionally, the name of the cache file the controller should use (passing nil prevents caching). Using a cache can avoid the overhead of computing the section and index information.