I'm using NSFetchedResultsController to update my collection view when there're changes in the Persistent Store. My fetchedResultsController has predicate which indicates if the model object should appear in the collection view or not.
I'm not using cache for my fetchedResultsController. The managed object context which connected to my fetchedResultsController does listen to the notification NSManagedObjectContextDidSaveNotification and perform merge when the notification is fired.
This is the my code:
- (NSFetchedResultsController *) fetchedResultsController
{
if (fetchedResultsController == nil)
{
NSFetchRequest *fetchRequest = [NSFetchRequest new];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"ObjectInfo" inManagedObjectContext:self.managedObjectContext];
fetchRequest.entity = entityDescription;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(shouldShowInCollectionView == YES)"];
fetchRequest.predicate = predicate;
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO];
[fetchRequest setSortDescriptors:@[sortDescriptor]];
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController.delegate = self;
NSError *error;
[fetchedResultsController performFetch:&error];
}
return fetchedResultsController;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
switch (type)
{
case NSFetchedResultsChangeInsert:
[[dict objectForKey:@(type)] addObject:newIndexPath];
break;
case NSFetchedResultsChangeDelete:
[[dict objectForKey:@(type)] addObject:indexPath];
break;
case NSFetchedResultsChangeMove:
[[dict objectForKey:@(type)] addObject:@[indexPath, newIndexPath]];
break;
case NSFetchedResultsChangeUpdate:
[[dict objectForKey:@(type)] addObject:indexPath];
break;
default:
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
self.collectionView performBatchUpdates:^{
//Update all the changes
}
}
The problem is after the first time NSFetchedResultsController performs fetch. When there're updates in the Persistent Store and model objects which previously should appear on the collection view, now, after the update, shouldn't appear in the collection view, still appear because the fetchedResultsController doesn't update the delegate properly. If I call performFetch it returns the results it should, but I don't want to call performFetch every time there's a change (If I'll call it every time there's a change, I don't need the fetchedResultsController)
I think the problem is in the predicate but I can't manage to figure what the problem is or what I'm missing here.
Thanks