I’m working on the app that uses CoreData. There is location entity that holds latitude and longitude values. I’d like to fetch those entities sorted by distance to the user’s location.
I tried to set sort descriptor to distance formula sqrt ((x1 – x2)^2 + (y1 – y2)^2) but it fails with exception “… keypath … not found in entity”.
NSString *distanceFormula = [NSString stringWithFormat:@"sqrt(((latitude - %f) * (latitude - %f)) + ((longitude - %f) * (longitude - %f)))",
location.coordinate.latitude,
location.coordinate.latitude,
location.coordinate.longitude,
location.coordinate.longitude];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:distanceFormula ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSError *error;
NSArray *result = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
I’d like to fetch already sorted objects rather then fetch them all and then sort in the code.
Any tips appreciated.
NSSortDescriptorshould be initialised with a key string for a property of the object, not a query string. It means you should implement your distance formula as a method of your object.After doing so, it doesn’t really matter if you sort before or after fetching:
Another point. Your distance formula doesn’t work correctly, as lat. and long. don’t have the same scale, unless you’re on the equator. Use this:
If the distance is more than a few hundred kilometers, you need Spherical cosines law: