NSFetchedResultsControllerDelegate not firing
cocoa-touch, core-data, iphone, nsfetchedresultscontroller
Solution
If I change the `sectionNameKeyPath` from @"Client" to nil when I create the original `fetchedResultsController_`, both the `Project` entity creation and save indeed invoke the delegate methods!
fetchedResultsController_ =
[[NSFetchedResultsController alloc] initWithFetchRequest:request
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:@"ProjectsCache"];
Upon hyper scrutiny, that is what the CoreData Recipes example does. As my data gets more complex - I think I'm going to need that argument to help break the results up into sections but for now, it is nice to see the delegate handlers being invoked.
Problem
I can't figure out why, for the life of me, the NSFetchedResultsControllerDelegate methods are not firing when I add data to the underlying datastore. The data shows up immediately if I restart the iPhone application. I have subclassed UITableViewController and conform to NSFetchedResultsControllerDelegate: ``` @interface ProjectListViewController : UITableViewController <NSFetchedResultsControllerDelegate> { NSFetchedResultsController* fetchedResultsController_; NSManagedObjectContext* managedObjectContext_; } ``` I instantiate the NSFetchedResultsController and set the delegate to self: ``` // Controller fetchedResultsController_ = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"Client" cacheName:@"ProjectsCache"]; fetchedResultsController_.delegate = self; ``` I implement the delegate methods: ``` - (void)controllerWillChangeContent:(NSFetchedResultsController*)controller { NSLog(@"ProjectListViewController.controllerWillChangeContent"); // The fetch controller is about to start sending change notifications, so prepare the table view for updates. [self.tableView beginUpdates]; } - (void)controllerDidChangeContent:(NSFetchedResultsController*)controller { ... } - (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { ... } - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { ... } ``` I create the entity I wish to save: ``` Project* newProject = [NSEntityDescription insertNewObjectForEntityForName:@"Project" inManagedObjectContext:self.managedObjectContext]; ProjectDetailViewController* detail = [[ProjectDetailViewController alloc] initWithStyle:UITableViewStyleGrouped delegate:self selector:@selector(finishedAdding:) project:newProject]; ``` And later, I save it: ``` - (void)save { // NSLog(@"ProjectDetailViewController.save"); self.project.name = projectNameTextField_.text; NSError* error; BOOL b = [self.project.managedObjectContext save:&error]; if (!b) { NSLog(@"Error saving project!"); } else { NSLog(@"Project was successfully saved."); [delegate_ performSelector:selector_ withObject:self.project]; } [self dismissModalViewControllerAnimated:YES]; } ``` It all works just fine except for the fact that my delegate methods don't fire. Obviously my table view doesn't get updated and the only way to see the new data is to explicitly refresh or restart the app. I've looked through the CoreData Recipe app - but can't seem to find what I'm missing. Thoughts? -Luther