Search code examples
iosobjective-ccore-datansexpression

iOS core data sum data by date, month year


In iOS, I am trying to sum a core data field by day, month and year.I found some examples using NSExpression, but not this specific request.

Here is my data object:

data{
  amount:NSNumber
  date:NSDate
}

Looking to group the data by day, month, and year then sum the amounts.

Thanks.


Solution

  • 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"];