My name is Jake Marsh. I'm a software creator,

thingy designer, and technology writer. Subscribe via RSS or Twitter.

POWERED by FUSION

Custom Sections Title Selectors

Posted in code and ios

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