NSPredicate With FUNCTION Not Working
Asked Answered
E

2

2

My predicate keeps on crashing my app with the message Unsupported function expression FUNCTION(SELF, "filterDistanceWithLatitude:" , latitude, longitude). Does anyone know how to fix this?

- (void)setUpFetchedResultsController
{
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"NextTime"]; //Retrieve data for the place entity
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)]]; //How to sort it
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.context sectionNameKeyPath:nil cacheName:nil]; //Puts the data in a NSFetchedResultsController which is oddly located in CoreDataTableViewController //Puts the data in a NSFetchedResultsController which is oddly located in CoreDataTableViewController
    self.filtered = self.fetchedResultsController.fetchedObjects;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FUNCTION(self, 'filterByDistanceWithLatitude:', latitude, longtitude) > 20"];
    self.filtered = [self.filtered filteredArrayUsingPredicate:predicate];
}

- (double)filterByDistanceWithLatitude:(NSNumber *)latitude andLongitude:(NSNumber *)longitude
{
    CLLocationDegrees latitudeCoor = [latitude doubleValue]; //Puts the latitude into a NextTime object.
    CLLocationDegrees longitudeCoor = [longitude doubleValue]; //Puts the longtitude into a NextTime object.

    CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:latitudeCoor longitude:longitudeCoor];
    CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:self.currentLocation.latitude longitude:self.currentLocation.longitude];

    NSNumber *distance = [[NSNumber alloc] initWithDouble:[loc1 distanceFromLocation:loc2]];

    return [distance doubleValue];
}
Estis answered 8/11, 2012 at 15:53 Comment(0)
C
2

A fetch request for a (SQL based) Core Data store cannot use Objective-C based predicates or sort descriptors. You can only filter on attributes stored in the data base.

Here is the relevant documentation from the "Core Data Programming Guide":

You cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself). ... To summarize, though, if you execute a fetch directly, you should typically not add Objective-C-based predicates or sort descriptors to the fetch request. Instead you should apply these to the results of the fetch.

There are some interactions between fetching and the type of store. ... The SQL store, on the other hand, compiles the predicate and sort descriptors to SQL and evaluates the result in the database itself. This is done primarily for performance, but it means that evaluation happens in a non-Cocoa environment, and so sort descriptors (or predicates) that rely on Cocoa cannot work.

Colorimeter answered 8/11, 2012 at 16:5 Comment(4)
So is there another way to approach this using NSPredicateEstis
@gsapienza: Not in combination with a fetched results controller. But you could fetch all objects (using NSArray *allObjects = [context executeFetchRequest:...], without a restricting predicate), and then apply the filter to the resulting array (e.g. NSArray *filteredObjects = [allObjects filteredArrayUsingPredicate:predicate].Colorimeter
Updated the code for that, still have the same error. Is my predicate formatted correctly?Estis
@gsapienza: I have seen "FUNCTION(...)" only with NSExpression, but not with NSPredicate. I would use a block-based predicate (predicateWithBlock) to filter the array.Colorimeter
W
0

'filterDistanceWithLatitude:' probably should be 'filterByDistanceWithLatitude:'

Walker answered 8/11, 2012 at 16:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.