views:

95

answers:

1

I'm using NSFetchedResultsController pretty much out-of-box in the way that the documentation describes. Here is an excerpt of my code.

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SomeEntity"
                                          inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];

NSPredicate *somePredicate = [NSPredicate predicateWithFormat:@"ANY buckets.name == %@", bucketId];
[fetchRequest setPredicate:somePredicate];

frc = [[NSFetchedResultsController alloc] 
       initWithFetchRequest:fetchRequest
       managedObjectContext:moc
       sectionNameKeyPath:@"titleAccessor"
       cacheName:@"frc"];
[fetchRequest release];

Notice two things:

1) the predicate. In my data model, SomeEntity and buckets have many-to-many relation. The predicate says "return all SomeEntity objects whose related bucket object has this name". Works as expected.

2) I'm using sectionNameKeyPath. It is actually a method in the model object that does some calculation according to some app logic and returns the title. Works as expected.

Now, the question:

How do I connect these two things and make the "titleAccessor" method aware of the predicate? I would like the section titles to be different depending on the predicate (to be precise, depending on the bucketId that I am using in the predicate). To make it clear:

right now the titleAccessor works so:

return @"result of some calculation"

I would like to make it work so:

if (bucketId == a):
    return @"aPrefix" + @"result of some calculation"
else if (bucketId == b):
    return @"bPrefix" + @"result of some calculation"

I have two trains of thought: 1) if this was a normal CD fetch (if there is such a thing), I could just set some volatile property of the model objects and use that. But, I don't have access to NSFetchedResultsController result objects. 2) if this was SQL, I'd do something like 'select a, b, c as "something" from blah;' at runtime, where "c" would then be the desired value and I could then use it as a property. But, this is not SQL. :)

How do I accomplish the desired behavior described above?

UPDATE:

Of course, you figure out the answer yourself right after posting the question. (I guess posting is part of the therapy.) I just realized that I put the following in my tableviewcontroller delegate as the documentation says:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[frc sections] objectAtIndex:section];
    return [sectionInfo name];
}

I could just do the necessary mangling here. Is that the best approach? Say "yes" and make some easy points. :) (or suggest an even better approach.)

A: 

That does seem like the cleanest approach that I can think of. There is no way that I know of that an entity can reach back to the predicate that fetched it.

Marcus S. Zarra
Also good for MVC separation, keep the UI stuff out of M and let VC do the conversion to UI strings.
Jaanus