Dave DeLong's approach is good, at least in my case, as long as you omit a couple of things. Here's how it's working for me:
Add a new optional string attribute
to the entity called
"lastNameInitial" (or something to
that effect).
Make this property transient. This
means that Core Data won't bother
saving it into your data file. This
property will only exist in memory,
when you need it.
Generate the class files for this
entity.
Don't worry about a setter for this
property. Create this getter (this is
half the magic, IMHO)
// THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL
- (NSString *) committeeNameInitial {
[self willAccessValueForKey:@"committeeNameInitial"];
NSString * initial = [[self committeeName] substringToIndex:1];
[self didAccessValueForKey:@"committeeNameInitial"];
return initial;
}
// THIS GOES IN YOUR fetchedResultsController: METHOD
// Edit the sort key as appropriate.
NSSortDescriptor *nameInitialSortOrder = [[NSSortDescriptor alloc]
initWithKey:@"committeeName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];
PREVIOUSLY: Following Dave's initial steps to the letter generated issues where it dies upon setPropertiesToFetch with an invalid argument exception. I've logged the code and the debugging information below:
NSDictionary * entityProperties = [entity propertiesByName];
NSPropertyDescription * nameInitialProperty = [entityProperties objectForKey:@"committeeNameInitial"];
NSArray * tempPropertyArray = [NSArray arrayWithObject:nameInitialProperty];
// NSARRAY * tempPropertyArray RETURNS:
// <CFArray 0xf54090 [0x30307a00]>{type = immutable, count = 1, values = (
// 0 : (<NSAttributeDescription: 0xf2df80>),
// name committeeNameInitial, isOptional 1, isTransient 1,
// entity CommitteeObj, renamingIdentifier committeeNameInitial,
// validation predicates (), warnings (), versionHashModifier (null),
// attributeType 700 , attributeValueClassName NSString, defaultValue (null)
// )}
// NSInvalidArgumentException AT THIS LINE vvvv
[fetchRequest setPropertiesToFetch:tempPropertyArray];
// *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
// reason: 'Invalid property (<NSAttributeDescription: 0xf2dfb0>),
// name committeeNameInitial, isOptional 1, isTransient 1, entity CommitteeObj,
// renamingIdentifier committeeNameInitial,
// validation predicates (), warnings (),
// versionHashModifier (null),
// attributeType 700 , attributeValueClassName NSString,
// defaultValue (null) passed to setPropertiesToFetch: (property is transient)'
[fetchRequest setReturnsDistinctResults:YES];
NSSortDescriptor * nameInitialSortOrder = [[[NSSortDescriptor alloc]
initWithKey:@"committeeNameInitial" ascending:YES] autorelease];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:nameInitialSortOrder]];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"committeeNameInitial" cacheName:@"Root"];