You can have a transient attribute for the date components. You have to add these to the managed object model as transient and to the entity subclass. They can be calculated like this:
-(NSNumber*)year {
NSCalendar *greg = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [greg components:NSYearCalendarUnit fromDate:self.date];
return @(comps.year);
}
Do the equivalent with months and days by devising a scheme that captures the relevant parts of the date in some primitive numeric form, e.g. days:
-(NSNumber*)day {
NSCalendar *greg = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [greg
components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:self.date];
return @(comps.year*10000+comps.month*100+comps.day);
}
(With the above scheme, that is really all you need. But having explicit year
and month
attributes will make your code more readable.)
Now to group in a NSFetchedResultsController
you can have year
or day
as the sectionNameKeyPath
. You can also group/filter with predicates like this:
NSArray *dataFor2000 = [allData filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"year = %@", @2000]];
Calculating the sum is trivial with key paths:
NSNumber *sum = [dataFor2000 valueForKeyPath:@"@sum.amount"];