Vasily
Vasily

Reputation: 3790

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.

Upvotes: 2

Views: 151

Answers (2)

Vasily
Vasily

Reputation: 3790

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)

Upvotes: 1

Wain
Wain

Reputation: 119031

It isn't documented terribly well what the different background context options should be used for and how. Likely worth raising an issue / submitting a PR.

Your issue is that performInNewBackgroundContext doesn't merge changes into the main context. This is because the context hierarchy isn't prescribed, so you can choose what you want to do.

So, you can either monitor the save and merge the changes yourself. Or you could set the parent context. Or you could use newBackgroundContext (which does merge changes automatically, even though that's a bit weird...).

Upvotes: 0

Related Questions