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