Search code examples
swiftcore-datansfetchedresultscontroller

NSFetchedResultsController doesn’t update from background contexts (DATAStack)


I’m using NSFetchedResultsController and DATAStack. My NSFetchedResultsController doesn’t update my table if I make any changes in another contexts.

I use dataStack.mainContext in my NSFetchedResultsController. If I do any updates from mainContext everything is okay. But if I write such code for example:

        dataStack.performInNewBackgroundContext({ (backgroundContext) in
            // Get again NSManagedObject in correct context, 
            // original self.task now in main context
            let backTask = backgroundContext.objectWithID(self.task.objectID) as! CTask

            backTask.completed = true
            let _ = try? backgroundContext.save()
        })

NSFetchedResultsController doesn’t update cells. I will see updated data if I reload application or whole view for example.

There is no error in data saving (I’ve checked).

I’ve tried to check NSManagedObjectContextDidSaveNotification is received, but if I do .performFetch() after notification is received I again get old data in table.


Solution

  • Finally I’ve got it, it’s not context problem.

    I’ve used such type of code in didChangeObject func in NSFetchedResultsControllerDelegate if NSFetchedResultsChangeType is Move (that event was generated because of sorting I think):

    guard let indexPath = indexPath, newIndexPath = newIndexPath else { return }
    _tableView?.moveRowAtIndexPath(indexPath, toIndexPath: newIndexPath)
    

    And that’s incorrect (I don’t know why NSFetchedController generates move event without «reload data event» if data was changed), I’ve replaced it with next code and everything now is working.

    guard let indexPath = indexPath, newIndexPath = newIndexPath else { return }
    _tableView?.deleteRowsAtIndexPaths([indexPath], withRowAnimation:   UITableViewRowAnimation.Fade)
    _tableView?.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)