Search code examples
core-dataiosnsfetchedresultscontrollernspredicate

NSFetchedResultsController with NSPredicate not updating


I fetch data from a Core Data-base and present them in a UITableView. I use a NSFetchedResultController to fetch the data. I want the user to be able to search in the database, and to do that I use a NSPredicate.

The data is presented in the UITableView and everything works well until I set the NSPredicate to the NSFetchedResultController.

I use this in the ViewDidLoad method:

    self.fetchedResultsController = nil;
fetchedResultsController_ = nil;

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

and when the user has entered a text from the UITextField, that text will go to the new NSPredicate.

This is done when the search starts:

NSPredicate *pred = nil;
pred = [NSPredicate predicateWithFormat:@"(Designation BEGINSWITH '22')"];
[fetchedResultsController_.fetchRequest setPredicate:pred];

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

[tView reloadData];

Right now I use @"(Designation BEGINSWITH '22')" for testing only.

This is my NSFetchedResultsController:

    - (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController_ != nil) {
        return fetchedResultsController_;
    }

    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Product" inManagedObjectContext:importContext];//self.managedObjectContext
    [fetchRequest setEntity:entity];

    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Designation" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:importContext sectionNameKeyPath:nil cacheName:@"Root"]; //self.managedObjectContext

    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    return fetchedResultsController_;
}    

The problem is that the fetched data stays the same, no matter how or if I set a predicate. If I would set a predicate in the viewDidLoad it would work, but then I wouldn't be able to get new results if I'd tried that again. I use an "importContext" for a batch-import of my CoreData.

Any ideas?

Thanks in advance!

UPDATE: Ok, here is what I found out. I have an importContext where I make a batch-import. And for the fetchController I use self.managedObjectContext. That's why it doesn't work, so I have to make self.managedObjectContext have the same stuff as my importContext somehow...


Solution

  • You're using a cache (@"Root")… Try setting it to nil, this could prevent crashes. You should not cache FetchedResultsControllers meant to be Predicated.