Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does CoreData on iPhone support IN predicates?

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?

like image 664
deeje cooley Avatar asked Sep 16 '09 23:09

deeje cooley


People also ask

What is predicate in Core Data?

The predicate instance constrains the selection of objects the NSFetchRequest instance is to fetch. If the predicate is empty—for example, if it is an AND predicate whose array of elements contains no predicates—the request has its predicate set to nil . For more about predicates, see Predicate Programming Guide.

What is Core Data in iOS?

Overview. Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.

Is Core Data a Threadsafe?

Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.


1 Answers

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.

like image 100
Wil Shipley Avatar answered Oct 17 '22 01:10

Wil Shipley