views:

720

answers:

2

I'm trying to fetch a bunch of records of a certain type, based on a list of types defined by the user…

[fetchRequest setEntity:[NSEntityDescription entityForName:@"myRecord" inManagedObjectContext:self.managedObjectContext]]; 
NSSet *shipTypes = [NSSet setWithObjects:[NSNumber numberWithInt:70],
     [NSNumber numberWithInt:71],
     [NSNumber numberWithInt:72],
     [NSNumber numberWithInt:73],
     [NSNumber numberWithInt:74],
      nil];
NSPredicate *aPredicate = [NSPredicate predicateWithFormat:@"type in %@", shipTypes];
[fetchRequest setPredicate:aPredicate];
theRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];

…when run, the executeFetchRequest message throws an exception…

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (type IN {71, 73, 70, 72, 74})'

Have I done something wrong, or is this really not supported?

+6  A: 

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.

Wil Shipley
It works using NSArray, rather than NSSet. Thanks to all for catching this.
deeje cooley
A: 

Try changing your predicate to @"ANY type IN %@"

thaDukeW