NSFetchedResultsController returning 0 sections in Xcode 8.1, worked in 8.0

My app builds a table view using an NSFetchedResultsController to pull from Core Data. In Xcode 8, my table view was working fine; however, upon updating to Xcode 8.1, and without changing any code, the results controller seems to be no longer pulling results from Core Data.


I am not getting any error messages or warnings.


Results in debug look like:

-----------------------------------

(lldb) po fetchedResultsController

▿ Optional<NSFetchedResultsController>

(lldb) p fetchedResultsController

(NSFetchedResultsController<NSManagedObject>?) $R1 = 0x00006000000eda00 {

ObjectiveC.NSObject = {}

}

(lldb) p fetchedResultsController.fetchedObjects

([NSManagedObject]?) $R2 = 0 values

-----------------------------------


In a CoreDataTableViewController.swift parent class, the initializers for the fetched results controller:

    var fetchedResultsController: NSFetchedResultsController<NSManagedObject>! {
        didSet {
            fetchedResultsController.delegate = self
            executeSearch()
            tableView.reloadData()
        }
    }

    init(fetchedResultsController frc: NSFetchedResultsController<NSManagedObject>, style : UITableViewStyle = .plain) {

            fetchedResultsController = frc

            super.init(style: style)
    }


In the RouteTableVeiwController.swift subclass, the initialization of the fetched results controller:

  let request: NSFetchRequest<Route> = Route.fetchRequest()
  let routeTypeSort = NSSortDescriptor(key: "route_type", ascending: true)
  let routeShortNameSort = NSSortDescriptor(key: "route_short_name", ascending: true)
  request.sortDescriptors = [routeTypeSort, routeShortNameSort]

  let mainContext = CoreDataStack.shared.persistentContainer.viewContext

  let routeTableFetchedResultsController: NSFetchedResultsController<Route> =
  NSFetchedResultsController(fetchRequest: request,
                             managedObjectContext: mainContext,
                             sectionNameKeyPath: "route_type",
                             cacheName: nil)

  fetchedResultsController = routeTableFetchedResultsController as! NSFetchedResultsController<NSManagedObject>


And, executeSearch():func executeSearch(){

  do{
    try fetchedResultsController.performFetch()
    // also tried this:
    // try (fetchedResultsController as! NSFetchedResultsController<Route>).performFetch()
  }
  catch { ... }

Accepted Reply

The last thing you ever check when a TV doesn't work: is the TV actually plugged in? The fetched results controller is returning no data because there was no data. When I actually decided to look at the SQLite, it was empty!


My app contains preloaded data files. If the .sqlite files don't exist, it's supposed to copy the preloaded files into the directory. However, apparently something changed in Xcode 8.1 such that the empty .sqlite files are being created before `didFinishLaunchingWithOptions` has completed. In Xcode 8, the files weren't present yet, and so the preloaded files got moved over as expected - so I didn't think to check for missing data. Ha!

Replies

The last thing you ever check when a TV doesn't work: is the TV actually plugged in? The fetched results controller is returning no data because there was no data. When I actually decided to look at the SQLite, it was empty!


My app contains preloaded data files. If the .sqlite files don't exist, it's supposed to copy the preloaded files into the directory. However, apparently something changed in Xcode 8.1 such that the empty .sqlite files are being created before `didFinishLaunchingWithOptions` has completed. In Xcode 8, the files weren't present yet, and so the preloaded files got moved over as expected - so I didn't think to check for missing data. Ha!