OMGPOP
OMGPOP

Reputation: 931

core data fetch request crash without error log

Contact entity has a many to one relationship to user, which has a userID field

Contact has a status string attribute that can be either 'approved', 'rejected', 'pending' etc

favorite boolean attributes

+ (NSSet *)fetchContactsWithUserID:(NSString *)userID approvedOnly:(BOOL)approvedOnly favoriateOnly:(BOOL)favoriateOnly {


    NSString *predString = [NSString stringWithFormat:@"(user.userID = %@)", userID];
    if (approvedOnly) {
        predString = [predString stringByAppendingString:@" AND (status = approved)"];
    }
    if (favoriateOnly) {
        predString = [predString stringByAppendingString:@" AND (favorite = YES)"];
    }

    NSPredicate *pred = [NSPredicate predicateWithFormat:predString];


    return [self private_fetchEntitiesWithName:@"Contact" predicate:pred];
}

+ (NSSet *)private_fetchEntitiesWithName:(NSString *)name predicate:(NSPredicate *)predicate {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:name inManagedObjectContext:[self private_context]];
    [fetchRequest setEntity:entity];

    if (predicate) {
        [fetchRequest setPredicate:predicate];
    }

    NSError *error;

    NSArray *fetchedObjects = [[self private_context] executeFetchRequest:fetchRequest error:&error]; //CRASH ON THIS LINE!!!!!!
    return [NSSet setWithArray:fetchedObjects];
}

stack trace:

enter image description here

There is no error logged out (i already enabled nszombie)

Upvotes: 0

Views: 411

Answers (1)

Matthias Bauch
Matthias Bauch

Reputation: 90117

@"(status = approved)" is not a valid predicate. If approved is a string your predicate string should be @" AND (status = \"approved\")" or @" AND (status = 'approved')".

If you use a string literal directly in a predicate you have to enclose it in quotes.

Strings that are not enclosed in quotes are treated as keys by the NSFetchRequest.
This is done because you can actually check if two attributes are equal by using a predicate that compares those two, e.g.@"attribute1 = attribute2".


If you use a predicate format that contains %@, NSPredicate will automatically add quotes if the object you want to use as argument is a NSString.

NSPredicate *p1 = [NSPredicate predicateWithFormat:@"foo = %@", @"Bar"];
NSPredicate *p2 = [NSPredicate predicateWithFormat:@"foo = Bar"];

NSLog(@"%@", p1);
NSLog(@"%@", p2);

yields:

xxx[4673:70b] foo == "Bar"
xxx[4673:70b] foo == Bar

Upvotes: 2

Related Questions