Jason Hocker
Jason Hocker

Reputation: 7067

NSFetchedResultsController with item in multiple sections?

I have a managed object to represent a spot on a map. These points have zero-many types. I want to also show a sectioned table view. I had this working with an NSFetchedResultsController when type was a single value on the MapPOI object. But now that the types are in a different objects with a relationship between "MapPOI" called "types", how do I write the query (can I?)

Original:

- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString
{
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MapPOI"];

    if(searchString.length)
    {
        request.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchString];
    }
    request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"type" ascending:YES ],[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES ],nil ];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                                                managedObjectContext:self.campus.managedObjectContext
                                                                                              sectionNameKeyPath:@"type"
                                                                                                       cacheName:nil];
    aFetchedResultsController.delegate = self;


    NSError *error = nil;
    if (![aFetchedResultsController performFetch:&error])
    {
       NSLog(@"Error performing institution fetch with search string %@: %@, %@", searchString, error, [error userInfo]);
    }

    return aFetchedResultsController;
}

i tried something like

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                                            managedObjectContext:self.campus.managedObjectContext
                                                                                              sectionNameKeyPath:@"types.name"
                                                                                                       cacheName:nil];

But that caused

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid to many relationship in setPropertiesToFetch: (types.name)'

Upvotes: 0

Views: 2434

Answers (1)

Mundi
Mundi

Reputation: 80265

The NSFetchedResultsController is very flexible and can be used with all kinds of views, not only table views.

The sectionNameKeyPath is of course wrong. It clearly has to be a to-one relationship. Assuming that one MapPOI can only have one type, the key path should be something like @"type.name".

If, however one MapPOI can have several types, you could do the following:

Fetch the types entity rather than the POI entity. You do not need a section key path. Now objectAtIndexPath:indexPath.row will fetch a Type managed object.

For number of sections use

self.fetchedResultsController.fetchedObjects.count

For section titles use

[[self.fetchedResultsController.fetchedObjects objectAtIndex:section] name];

For row count in section use

Type *type = [self.fetchedResultsController.fetchedObjects objectAtIndex:section];
type.mapPOIs.count; 

And it should be obvious how to populate the cell with the MapPOI entities.

Upvotes: 3

Related Questions