I'm working on my first Core Data-backed app and am having trouble figuring out how to set up an NSFetchedResultsController properly. I have two entities:
/-----------\ /-----------\
| List | | ListItem |
| --------- | | --------- |
| listName | | itemName |
| --------- | | --------- |
| listItems |<---->> | list |
\ --------- / \ --------- /
I have two views (each inherit from UITableViewController
and each are backed by a NSFetchedResultsController
). The first view is a UITableView
that displays all of the List
items. When a row is selected, it pushes the second view.
I have a property in the view controller called @property (strong, nonatomic) List *selectedList
which I assign with the selected List
before I push the view.
What I'm having trouble setting up is having the second view only display the ListItem
objects whose parent is the selected List
. I know that this belongs somewhere in the NSFetchedResultsController
, but I don't know quite where.
Here's my code:
- (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:@"ListItem" inManagedObjectContext: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:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects: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:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Detail"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __fetchedResultsController;
}
Do I need to add some sort of a sort descriptor, or does the answer lie with something else? Thanks!
You need an NSPredicate
to select the ListItem
s where selectedList
matches their list
property.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"list == %@", self.selectedList];
[fetchRequest setPredicate:predicate];
There's one thing to be aware of here and that is that the predicate will change depending on selectedList
meaning that the fetch request will change. If you will be changing the fetch request, Apple has this warning in the NSFetchedResultsController
Class Reference.
You cannot simply change the fetch request to modify the results. If you want to change the fetch request, you must:
If you are using a cache, delete it (using
+deleteCacheWithName:
).Typically you should not use a cache if you are changing the fetch request.
Change the fetch request. Invoke
-performFetch:
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With