3

I'm building an iOS app using RestKit and NSFetchedResultsController in my ViewControllers like explained in the following tutorial : http://www.alexedge.co.uk/blog/2013/03/08/introduction-restkit-0-20

I have a subclass of a UITableViewController that displays the data fetched by the NSFetchedResultsController and it works well.

Now I want to filter the displayed data so I'm adding a predicate to the fetch request of the NSFetchedResultsController and performing the fetch again (I don't use any cache) :

[self.fetchedResultsController.fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"title like 'some text'"]];
NSError *error = nil;

[self.fetchedResultsController performFetch:&error];

NSAssert(!error, @"Error performing fetch request: %@", error);

No error happens but the table view is not updated. I was expecting this method to be called

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;

but it's not...

Worse, when I log the number of fetched objects like this

NSLog(@"before refetch : %d objects", self.fetchedResultsController.fetchedObjects.count);

[...]

NSLog(@"after refetch : %d objects", self.fetchedResultsController.fetchedObjects.count);

I'm getting

before refetch : 18 objects
after refetch : 0 objects

(That's probably why my app crashes as soon as I try to scroll the table view)

So how should I refresh the content of the NSFetchedResultsController so that controllerDidChangeContent is called and thus I can reload the table view ? and also that fetchedObjects contains something...

EDIT: If at this moment I call the RestKit object manager to get the data displayed in the table view AND a Internet connection is available THEN the NSFetchedResultsController gets updated and the table view as well with the correct result of the fetch request WITH the predicate.

EDIT: The predicate I use is the cause of the problem (I think). My entity has a transformable attribute which is parsed from an JSON array of strings and the predicate test if a search string exists in that array:

[NSPredicate predicateWithFormat:@"ANY transformable_attribute like 'search string'"]

The weird thing is that if I load the results without predicate and add it afterwards then I get 0 object BUT if I load the results directly with the predicate then I get 3 objects. Is my predicate wrong?

EDIT: yes it is! Looks like we can't predicate on transformable attributes. I don't know why it works the first time.

Alexis
  • 16,629
  • 17
  • 62
  • 107

2 Answers2

4

Changing the predicate of a NSFetchedREsultsController does not result in a delegate call to controllerDidChangeContent. From the documentation:

An instance of NSFetchedResultsController uses methods in this protocol to notify 
its delegate that the controller’s fetch results have been changed due to an add, 
remove, move, or update operations.

The solution is to reload the table with

[tableView reloadData]
GoZoner
  • 67,920
  • 20
  • 95
  • 145
4

Your predicate is a constraint that leads to 0 results. That is probably expected behavior. Check what is in the data store and you will most likely find that it follows the logic of the predicate and your data.

You will need to change your predicate to get the results you intended.

Call

[self.tableView reloadData]; 

after performing the fetch to update the table.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • This is the weird part of it. When I load the results for the first time I'm getting 18 objects then when I add the predicate I get 0 object. But if I load the results for the first time WITH the predicate then I get 3 objects – Alexis Aug 23 '13 at 06:35
  • Sounds like either the predicate or the data are different in the two cases. – Mundi Aug 23 '13 at 09:46