Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iCloud and Core Data. NSFetchedResultsController doesn't update on initial sync

iCloud and Core Data are working great. Except...

On initial app launch (existing iCloud data is there), NSFetchedResultsControllers don't update as the received data comes through. NSFetchedResultsController delegates just don't get called. On force quitting and relaunching the app all the data is there as it should be.

Core data code is the same as the excellent tutorial here. I have a feeling this code isn't wrong as I've used this for another app, and didn't have this problem.

Other info: My managed object context is initialised with main queue concurrency. The only thing I've managed to figure out is that I can catch the initial data as it comes through - the below function gets called a few seconds after the app is initially launched. However, although the data comes through, existing fetched results controllers don't seem to be updated accordingly (but creating them again shows the data).


- (void)storesWillChange:(NSNotification *)notification {
    NSManagedObjectContext *context = self.managedObjectContext;

    [context performBlockAndWait:^{
        NSError *error;

        if ([context hasChanges]) {
            BOOL success = [context save:&error];

            if (!success && error) {
                // perform error handling
                NSLog(@"%@",[error localizedDescription]);
            }
        }

        [context reset];
    }];

}


So: What can I do to start pinpointing why NSFetchedResultsControllers aren't updated as they should be?

like image 544
Jordan Smith Avatar asked Mar 25 '14 12:03

Jordan Smith


1 Answers

I am guessing a bit here, but think because you are resetting the context immediately after saving, that the NSFetchedResultsController delegate methods aren't picking up on this because of the reset. What I mean is the delegate methods are intended to deal with things like a selection of records changing within the current result set (inserts, updates or deletes of the records currently tracked by the fetched results controller).

When you perform a context reset you blow all of this away, and hence these delegate methods don't get called as what they were tracking doesn't exist any longer in a form that it recognises.

Whenever I reset a context due to incoming iCloud updates I usually ensure that I recreate my fetched results controller for the newly reset context.

Force quitting the app will force the fetched results controller to be recreated on relaunch, hence showing the data as you expect to see it.

like image 110
Rob Glassey Avatar answered Oct 05 '22 21:10

Rob Glassey