0

i'm trying to group and count on date on a core data entity. since date cant be group due to different time. so i'm trying to pass custom function to nsexpression. but i get some errors i dont know what's the correct way to do it.

code for grouping and counting:

NSEntityDescription *entity     = [NSEntityDescription entityForName:@"TEvents"
                                              inManagedObjectContext:context];
NSDictionary *props = [entity propertiesByName];

NSPropertyDescription *propDesc3 = [props objectForKey:@"startDateTime"];
NSExpression *propExpr3 = [NSExpression expressionForKeyPath:@"startDateTime"];
NSExpression *countExpr3 = [NSExpression expressionForFunction:propExpr3 selectorName:@"dateShort" arguments:nil];
NSExpressionDescription *exprDesc3 = [[NSExpressionDescription alloc] init];
[exprDesc3 setExpression:countExpr3];
[exprDesc3 setExpressionResultType:NSDateAttributeType];
[exprDesc3 setName:@"dateStart"];


NSFetchRequest *fr = [NSFetchRequest fetchRequestWithEntityName:@"TEvents"];
[fr setPropertiesToGroupBy:[NSArray arrayWithObjects:propDesc3, nil]];
[fr setPropertiesToFetch:[NSArray arrayWithObjects:propDesc3, exprDesc3, nil]];
[fr setResultType:NSDictionaryResultType];
NSError * error = nil;
NSArray *results = [context executeFetchRequest:fr error:&error];

dateShort is a nsdate category function which converts datatime to user's current zone:

-(NSString *) dateShort
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setCalendar:[NSCalendar currentCalendar]];
[formatter setTimeZone:[NSTimeZone localTimeZone]];
[formatter setDoesRelativeDateFormatting:YES];
[formatter setDateStyle:NSDateFormatterShortStyle];
[formatter setTimeStyle:NSDateFormatterNoStyle];

NSString *tmpValue = [formatter stringFromDate:self];
return tmpValue;
}

error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported function type passed to SQL store'

how to achieve this goal: convert datetime to current zone and group and count on (yy-mm-dd) on a core data entity?

Hashmat Khalil
  • 1,826
  • 1
  • 25
  • 49

2 Answers2

0

I think you are on the wrong path here. There is a much simpler solution to your problem.

You should use a NSFetchedResultsController and use a transient property on your entity to serve as the section header. You calculate the date in a category of your managed object subclass. Then it is as simple as specifying your transient property name in the sectionNameKeyPath when creating the fetched results controller.

Apple has a good working example that for most purposes you can use out of the box.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • i have right now the nsfetchedresultcontroller with transient property cor converting UTC date. that works perfectly. beside that i have to group and count on more than one property. and i have to notify the fetchedresultcontroller of changes when background context adds records, and then regroup and recount. i'm struggling with it. i'm going to take a look at linked example. – Hashmat Khalil Sep 22 '13 at 12:05
  • apple's example is very simple and ok for date conversion. what i actually need to know is how to combine all those tricks together. first convert dateTime, then group & count on date and event type. and still be able to have 1-to-many relationship. so that detail view can show not only the grouped event but also information from the relationship. – Hashmat Khalil Sep 22 '13 at 12:17
  • That seems trivial. Can you explain in plain English the logic you want to implement? – Mundi Sep 22 '13 at 16:12
  • sorry for my bad english skills :). first the tables are in relationship A <<---> B. i have to group and count on date(utc) and event type from table A. but first i have to convert utc date to local time date. then somehow remove the time so that grouping happen only on dd-mm-yy and sort on the calculated dd-mm-yy. if date is older than a week then show date only. if date is older than today and smaller than a week then show Sat-Sun-Mon... if date is equal to today then show hh:mm only. is it understandable? :) – Hashmat Khalil Sep 22 '13 at 17:19
  • apple's example only converts date on transient property. that's ok but if you want to group on it then it wont work. grouping on transient property is not allowed and shows exception. and grouping on nsdate is really a nightmare. i mean nsdate contains time too so wont group. we can save date only to other property but it wont be correct for the local time. so i'm stuck with this problem. – Hashmat Khalil Sep 22 '13 at 17:27
0

I had to use NSExpression to achieve the goal. NSfetchResultController cannot group.

Hashmat Khalil
  • 1,826
  • 1
  • 25
  • 49
  • NSFetchRequest has some good properties "propertiesToFetch" and "propertiesToGroupBy". so basically create array of type NSPropertyDescription pointing to column. you can combine NSPropertyDescription with NSExpression with aggregation functions. – Hashmat Khalil Jun 08 '15 at 09:01
  • How did you implement this using NSExpression? – Kukiwon Mar 20 '23 at 20:13