Does CoreData on iPhone support IN predicates? Does CoreData on iPhone support IN predicates? sqlite sqlite

Does CoreData on iPhone support IN predicates?


I believe Alex is right that you have to use an NSArray, although obviously it'd be nicer if NSSet were accepted here, since order isn't that important (although it could conceivably affect how quickly the SQL can run).

As a side note, I never use the +predicateWithFormat: call in any code, ever, because it can't do compile-time sanity or type-checking. I highly advise using the individual classes.

In this case, I'd do:

fetchRequest.entity = [NSEntityDescription entityForName:@"myRecord" inManagedObjectContext:self.managedObjectContext]];NSArray *shipTypes = [NSArray arrayWithObjects:[NSNumber numberWithInt:70],                                        [NSNumber numberWithInt:71],                                        [NSNumber numberWithInt:72],                                        [NSNumber numberWithInt:73],                                        [NSNumber numberWithInt:74],                                         nil];fetchRequest.predicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:@"type"] rightExpression:[NSExpression expressionForConstantValue:shipTypes] modifier:NSDirectPredicateModifier type:NSInPredicateOperatorType options:0];theRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

Not that this would have caught this particular error at compile time, but it WOULD have potentially caught it at the NSExpression level, thus making it much clearer what went wrong.


Hmm. I tried both adding the ANY keyword and using NSArray. Actually I was using NSAArray to start with when I got this exception from Core Data. In retrospect think that because I was combining two expressions with AND it was a problem for Core Data. (I know I should go back and verify this but this thought just occurred to me, while reading this post.) Here is my original expression:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"BPM BETWEEN { %d, %d } AND GENRE IN %@", lower, upper, genres];

My solution was to break it up into two parts. Now, I issue the query for the BPM using the predicate but I take the resulting array and use -filteredArrayUsingPredicate with @"genre IN %@". Thus:

array = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"genre IN %@", genres]];

This works for me.


I struggled with this. Eventually I ended up doing a sub predicate for each of the set.

So for example:

NSMutableArray *subpredicates = [NSMutableArray array];NSArray *shipTypes = [NSArray arrayWithObjects:[NSNumber numberWithInt:70],                                    [NSNumber numberWithInt:71],                                    [NSNumber numberWithInt:72],                                    [NSNumber numberWithInt:73],                                    [NSNumber numberWithInt:74],                                     nil];for (NSNumber *num in shipTypes) {    [subpredicates addObject:[NSPredicate predicateWithFormat:@"ANY type == %@", num]];         }NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates];

That's assuming that type is a NSSet. If it's not you could just have:

for (NSNumber *num in shipTypes) {    [subpredicates addObject:[NSPredicate predicateWithFormat:@"type == %@", num]];         }