Master data: attempt to find the minimum date for an attribute in an entity

I am trying to find the oldest date in a specific attribute in Core Data. I found an example in the Master Data Programming Guide that tries to do just that, but keep getting the unrecognized selected error when it starts.

My code (with minimal changes in the Apple example):

NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext: ctx]; [request setEntity:entity]; // Specify that the request should return dictionaries. [request setResultType:NSDictionaryResultType]; // Create an expression for the key path. NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"startedAt"]; // Create an expression to represent the minimum value at the key path 'creationDate' NSExpression *minExpression = [NSExpression expressionForFunction:@"min:" arguments:[NSArray arrayWithObject:keyPathExpression]]; // Create an expression description using the minExpression and returning a date. NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; // The name is the key that will be used in the dictionary for the return value. [expressionDescription setName:@"minDate"]; [expressionDescription setExpression:minExpression]; [expressionDescription setExpressionResultType:NSDateAttributeType]; // Set the request properties to fetch just the property represented by the expressions. [request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]]; // Execute the fetch. NSError *error; NSArray *objects = [ctx executeFetchRequest:request error:&error]; 

And the error:

 -[NSCalendarDate count]: unrecognized selector sent to instance ... 

Which is strange, given that 1) NSCalendarDate is deprecated and 2) I definitely do not call the bill.

Any help would be appreciated!

+7
cocoa core-data nsfetchrequest
source share
2 answers

Why not just add a sort descriptor to sort by startedDate in ascending order, and then only the select query returns 1 object?

+12
source share

This is my code that works. I do not see a significant difference with your own code, and perhaps it is in the definition of the underlying data model. Make sure your date is NSDate and indexed.

 - (NSDate *)lastSync:(PHAssetMediaType)mediaType { NSEntityDescription *entity = [NSEntityDescription entityForName:kMediaItemEntity inManagedObjectContext:self.managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; fetchRequest.entity = entity; fetchRequest.resultType = NSDictionaryResultType; NSMutableArray *predicates = [NSMutableArray array]; [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaType,mediaType]]; [predicates addObject:[NSPredicate predicateWithFormat:@"%K=%d", kMediaProviderType,self.mediaProviderType]]; NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: predicates]; fetchRequest.predicate = predicate; // Create an expression for the key path. NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:kSyncTime]; // Create an expression to represent the function you want to apply NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:@[keyPathExpression]]; // Create an expression description using the maxExpression and returning a date. NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"maxDate"]; [expressionDescription setExpression:maxExpression]; [expressionDescription setExpressionResultType:NSDateAttributeType]; // Set the request properties to fetch just the property represented by the expressions. fetchRequest.propertiesToFetch = @[expressionDescription] ; // @[kSyncTime]; NSError *fetchError = nil; id requestedValue = nil; // fetch stored media NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&fetchError]; if (fetchError || results == nil || results.count == 0) { return [NSDate dateWithTimeIntervalSince1970:0]; } requestedValue = [[results objectAtIndex:0] valueForKey:@"maxDate"]; if (![requestedValue isKindOfClass:[NSDate class]]) { return [NSDate dateWithTimeIntervalSince1970:0]; } DDLogDebug(@"sync date %@",requestedValue); return (NSDate *)requestedValue; } 
0
source share

All Articles