Recently, I've been struggling with NSFetchedResultsController. I was trying to get it to section my objects by a "pretty date", but still have them sorted properly.
Thanks to a great post on stackoverflow, I realized the beauty and simplicity of just adding an Objective-C Category to the NSDate property on my model object.
My managed object had a property called scanTimestamp, which was an NSDate. When configuring the NSFetchedResultsController, I was able to simply use @"scanTimestamp.prettySectionHeaderDateSring" as the sectionKeyPath.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"PKScan" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scanTimestamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"scanTimestamp.prettySectionHeaderDateSring"
cacheName:nil];
Then, I just set scanTimestamp to be the sortDescriptor for the NSFetchRequest of the NSFetchedResultsController, and everything worked both smoothly, and correctly.
In the Category, the - (NSString *) prettySectionHeaderDateSring method was declared as returning an NSString and also as a readonly property (either of which would have been sufficient, but it's always nice to have both explicitly declared). Then I simply implemented the prettySectionHeaderDateSring method using some NSDateFormatter magic to transform the ugly "2010-10-13 10:33:12 -0400" NSDate value into a nice and pretty "Wednesday, October 13th" string.
Here's the NSDate category:
#import <Foundation/Foundation.h>
@interface NSDate (PrettySectionHeaderAdditions)
- (NSString *) prettySectionHeaderDateSring;
@end
@implementation NSDate (PrettySectionHeaderAdditions)
- (NSString *) prettySectionHeaderDateSring {
NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:@"EEEE, LLLL d"]; //Resolves to: "Wednesday, September 13"
[formatter setAMSymbol:@"am"];
[formatter setPMSymbol:@"pm"];
return [formatter stringFromDate:self];
}
@end