views:

65

answers:

0

I'm trying to use the NSFetchedResultsController in my app, but have a problem to sort my data. I get the following error when trying to sort the result using a relationship that is two levels down from the entity:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'

My data model is set up this way:

Item <<---> Category <--->> SortOrder <<---> Store

In other words: Each item belongs to one category. Categories can have different sort orders for each store that includes a certain category.

So, I'm creating a fetch request to find all items for a certain store and would like to present the result using category names as sections, and sorted on the sort order.

When I perform the the fetch (last line below), I get the above error.

 NSManagedObjectContext* context = [appDelegate managedObjectContext];
 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(status != %d) AND (ANY category.sort.include == YES) AND (ANY category.sort.store == %@)", ItemStatusDefault, store];

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:context];
 [fetchRequest setEntity:entity];
 [fetchRequest setPredicate:predicate];

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"category.sort.order" ascending:YES];
 NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
 [fetchRequest setSortDescriptors:sortDescriptors];
 [sortDescriptors release];
 [sortDescriptor release];

 self.resultsController = [[NSFetchedResultsController alloc]
             initWithFetchRequest:fetchRequest
             managedObjectContext:context
             sectionNameKeyPath:@"category.name"
             cacheName:nil];
 [fetchRequest release];

 NSError *error;
 BOOL success = [self.resultsController performFetch:&error]; 

If I change the sorting to, say, category names, it works.

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"category.name" ascending:YES];

How can I get the NSSortDescriptor to sort on the sort order?

UPDATE: So it seems this is not possible. I got a suggestion to create a transient property and sort on that, but Apple documentation clearly states

You cannot fetch using a predicate based on transient properties

My conclusion here is that I cannot use NSFetchedResultsController out of the box. I need to either access the array of objects the NSFetchResultsController gives me and sort in memory, or setup my own fetch requests and skip NSFetchedResultsController.