NSFetchedResultsController - changing the Runtime variable for Predicate

There are many questions on this topic, but perhaps too specific and not too succinct.

I have a NSFetchedResultsController. First, it fetches the data I need. When I update the data model that will affect the NSPredicate NSFetchRequest results, the content is not updated.

More specifically, I have a permission model. There are data objects that have been assigned permissions, then there are users who have a subset of those permissions, although the permission of the data object does not match the user's permission; they share the same control.

So NSPredicate:

[NSPredicate predicateWithFormat:@"controlKey IN %@", [[User currentUser].permissions valueForKey:@"controlKey"]];

      

The problem is that if I create and add the permission, the content is not updated when I save the NSManagedObjectContext (yes, I observe this. No, I do not use the cache to not delete anything).

I'm pretty convinced of this because of the predicate. It is still the same array as it was initially and is not updated.

My question is, how do I write a predicate that gets me what I want, but still remains "dynamic"? It would be nice to have the UITableView animate when this object is added.

+3


source to share


3 answers


I tried using the following piece of code and it works for me:



[NSFetchedResultsController deleteCacheWithName:nil];  
[self.fetchedResultsController.fetchRequest setPredicate:predicate];  // set your new predicate

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"%@, %@", error, [error userInfo]);
    abort();
} 

      

0


source


Here's what you need to do. When a change is detected

self.fetchedResultsController.predicate = //new predicate
[self.fetchedResultsController performFetch:nil];
[self.tableView reloadData];

      

Or sometimes it is necessary to clear the FRC.



_predicate = // new predicate, put it into an ivar
self.fetchedResultsController = nil;
[self.tableView reloadData];  // lazily re-instantiate FRC with _predicate

      

It can be expensive, but to get animation you can try replacing reloadData

like this:

[self.tableView beginUpdates];
[self.tableView endUpdates];

      

+2


source


You request control keys from a permission set and pass them to a predicate. The predicate itself is not dynamic, it is only the result of dynamic selection. Thus, you cannot do exactly what you want.

Instead, you should watch for the user rights change, a new predicate is created, the FRC is updated and re-executed (a requirement after the predicate change, since it must be static).

+1


source







All Articles