I have a project where I need to do a fetch request that gets the most recent 'updated' date of a Core Data entity. When I actually examine the results returned by my query however I am seeing some rather strange behaviour. In addition to the 'correct' result containing the date the results also include an empty dictionary item. This happens every time, regardless of what the underlying data looks like. Even stranger, if I turn on sql logging in xcode and execute the logged query against the sqllite db it produces the correct result with no extra entries. I'm not quite sure what I'm doing wrong here, any help would be appreciated.
The function that builds and executes the query:
func queryForContactDate(context:NSManagedObjectContext) -> AnyObject?
{
var expressionDescriptions = [AnyObject]();
let expressionDescription = NSExpressionDescription()
// Name the column
expressionDescription.name = "maxUpdated"
// Use an expression to specify what aggregate action we want to take and
// on which column. In this case max on the update_at column
expressionDescription.expression = NSExpression(format: "@max.updated_at")
// Specify the return type we expect
expressionDescription.expressionResultType = .DateAttributeType
// Append the description to our array
expressionDescriptions.append(expressionDescription)
// Build out our fetch request the usual way
let request = NSFetchRequest(entityName: Contact.entityName())
// Specify we want dictionaries to be returned
request.resultType = .DictionaryResultType
// Hand off our expression descriptions to the propertiesToFetch field.
request.propertiesToFetch = expressionDescriptions
// Our result is going to be an array of dictionaries.
var results:[[String:AnyObject]]?
// Perform the fetch. This is using Swfit 2, so we need a do/try/catch
do {
results = try context.executeFetchRequest(request) as? [[String:AnyObject]]
} catch _ {
// If it fails, ensure the array is nil
results = nil
}
return results![0];
}
If I put a breakpoint at the end and print out the results it produces:
Printing description of results:
▿ Optional([[:], ["maxUpdated": 2015-12-30 20:05:31 +0000]])
▿ Some : 2 elements
- [0] : 0 elements
▿ [1] : 1 elements
▿ [0] : 2 elements
- .0 : "maxUpdated"
- .1 : 2015-12-30 20:05:31 +0000
With most Core Data apps, you’re going to see a call to fetch (_:) somewhere in your code. This happens “behind the scenes” when you use the @FetchRequest property wrapper in your SwiftUI view. No need to use your managed object context to perform the fetch request manually.
With most Core Data apps, you’re going to see a call to fetch (_:) somewhere in your code. This happens “behind the scenes” when you use the @FetchRequest property wrapper in your SwiftUI view.
The executeFetchRequest:error: method has two possible results. It either returns an NSArray object with zero or more objects, or it returns nil. If nil is returned, you have received an error from Core Data and need to respond to it.
You have to learn all about the async nature of REST calls. the request is Asynchronous; you do not get an immediate response Your function getItems can not have a return value, as the Ajax request is still fetching your coffee. If you go with the Promises pattern you will do something like:
The traditional Core Data way to get a max or min item is to query with a fetch limit of 1 and sort on that key. As in this Objective-C code:
+ (NSFetchRequest *) requestForStatusWithMaxID {
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName: kAMStatusEntity];
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey: kAMTwID ascending:NO];
request.sortDescriptors = @[sd];
request.fetchLimit = 1;
return request;
} // +requestForStatusWithMaxID
It would be quite simple to modify the above for your updated_at
property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With