user1898829 user1898829 - 6 months ago 30
iOS Question

NSFetchedResultsControllerDelegate methods don't get called

I have this in my viewWillAppear method

[RPCoreData
getFetchedControllerForCategoryDiscoverDelegate:self completion:^(NSFetchedResultsController *controller) {
self.fetchedResultController = controller;
self.fetchedResultController.delegate = self;
}];


and this in my CoreData.m

+ (void)
getFetchedControllerForCategoryDiscoverDelegate:(id<NSFetchedResultsControllerDelegate>)delegate
completion:(void (^)(NSFetchedResultsController *controller))
completion {
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
NSFetchedResultsController *controller = [ItemData MR_fetchAllGroupedBy:@"category.id"
withPredicate:nil
sortedBy:@"category.id"
ascending:NO
delegate:delegate
inContext:localContext];
completion(controller);
}];
}

Answer

You don't need to wrap the creation of a NSFetchedResultsController around a saveWithBlock: from MagicalRecord since you are effectively only fetching objects, not changing them.

I do understand why you did it though (in order to get a local NSManagedObjectContext)

MagicalRecord has a convenience method that does not require you to pass a NSManagedObjectContext:

+ (NSFetchedResultsController *) MR_fetchAllGroupedBy:(NSString *)group withPredicate:(NSPredicate *)searchTerm sortedBy:(NSString *)sortTerm ascending:(BOOL)ascending;

This will use the context for the current thread you're in during execution, so if you're not doing anything too complex like switching between threads and managing different contexts, you should be fine with it.

This way your method should be able to return a NSFetchedResultsController right away, without using blocks.

Moreover, it seems like you are setting up the delegate twice, once inside the block and once when passed as a parameter to the MR_fetchAllGroupedBy:..

Finally, make sure your newly created NSFetchedResultsController is not nil, and implement one of delegate methods in the same class as your viewWillAppear:, then use breakpoints/logging to see if they are called:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    NSLog(@"objects: %@", controller.fetchedObjects);
}
Comments