Provided that I think this will work; I leave it to you to check it to death:
You cannot add any other attributes to propertiesToFetch other than those specified in propertiesToGroupBy , but it looks like you can include objectID in the properties to retrieve. To do this, create an NSExpression and its associated NSExpressionDescription for the "evaluated object":
NSExpression *selfExp = [NSExpression expressionForEvaluatedObject]; NSExpressionDescription *selfED = [[NSExpressionDescription alloc] init]; selfED.name = @"objID"; selfED.expression = selfExp; selfED.expressionResultType = NSObjectIDAttributeType;
Now define another expression / description to get max (date):
NSExpression *maxDate = [NSExpression expressionForKeyPath:@"date"]; NSExpression *indexExp = [NSExpression expressionForFunction:@"max:" arguments:@[maxDate]]; NSExpressionDescription *maxED = [[NSExpressionDescription alloc] init]; maxED.name = @"maxDate"; maxED.expression = indexExp; maxED.expressionResultType = NSDateAttributeType;
Then include these two expression descriptions in the property list to retrieve:
[request setPropertiesToFetch:@[@"phone", maxED, selfED]]; [request setPropertiesToGroupBy:@[@"phone"]];
When you start the selection, each element in the resulting array will have the key "objID" containing the identifier of the object for the corresponding object. You can unzip this to access the name, phone, etc., with something like this:
NSArray *results = [self.context executeFetchRequest:request error:&error]; for (NSDictionary *dict in results) { NSDate *maxDate = dict[@"maxDate"]; NSString *phone = dict[@"phone"]; NSManagedObjectID *objID = [dict valueForKey:@"objID"]; NSManagedObject *object = [self.context objectWithID:objID]; NSString *name = [object valueForKey:@"name"]; }
One specific aspect that I'm not sure about is how it will look if two strings have exactly the same date .
source share