I'm trying to find all customers that contain a certain sequence of letters. I want identical functionality to NSString's rangeofString except case insensative. Heres my method:
-(NSArray *) db_search: (NSString *) table where: (NSString*) fieldKey contains: (NSString*) value withSortField: (NSString *) sortField{
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:table inManagedObjectContext:context];
if (fieldKey != nil){
NSPredicate *predicate = [NSPredicate
predicateWithFormat:@"(%@ contains[c] %@)",
fieldKey,value];
[request setPredicate:predicate];
}
[request setEntity:entity];
if (sortField != nil){
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:[self extractSortField:sortField] ascending:[self isAscending:sortField]] autorelease];
NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortDescriptor, nil] autorelease];
[request setSortDescriptors:sortDescriptors];
}
NSError *error;
return [context executeFetchRequest:request error:&error];
}
I'm calling it with these values:
NSArray * results = [self db_search:@"Customer" where:@"fullname" contains:@"matt" withSortField:nil];
Instead of getting all Matts, Matthews, etc, it freezes when I try to print out the results. I debugged it and we don't even get an empty NSArray back. I print the NSArray to console and I don't get 0 elements.. I just get nothing.
I've tried doing a dump of the DB to console and it contains all the right things in it. HELP!!!
=UPDATE======================================================
I am using %K and I'm getting a wierd runtime error:
if (searchResults1 != nil){
NSLog(@"%Matches: %i", [searchResults1 count]);
}else {
NSLog(@"Was NULL");
}
Its on the NSLog(@"%Matches: line. Its a BAD EXC error. So searchResults1 is not nill but it crashes when I try to read the count? When I debug, searchResults1 is indeed an NSArray but it doesn't seem to have anything inside it.
It looks like your problem is your predicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(%@ contains[c] %@)", fieldKey,value];
When you pass in fieldKey = @"fullname"
and value = @"matt"
, this predicate is going to be equivalent to:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"('fullname' contains[c] 'matt')"];
Do you see the problem? It's treating "fullname" as a raw string, and not as the name of a field. This is because you're using the %@
modifier in the format string. When NSPredicate
comes across those, it says "aha! the value that gets substituted in here will be a constant". What you really want it to do is say "aha! the value that gets substituted in here will be an identifier".
So instead of using %@
, use %K
. This is a special modifier just for predicates, and it means to substitute in the string as an identifier (really as a "keypath"), which means it will make your predicate be:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(fullname contains[c] 'matt')"];
Which is what you're looking for.
I can tell from the way you named your variables and parameters that you are thinking in SQL terms. Core Data is not SQL. Entities are not tables. Objects are not rows. Columns are not attributes. Core Data is an object graph management system that may or may not persist the object graph and may or may not use SQL far behind the scenes to do so. Trying to think of Core Data in SQL terms will cause you to completely misunderstand Core Data and result in much grief and wasted time.
In this block:
if (searchResults1 != nil){
NSLog(@"%Matches: %i", [searchResults1 count]);
}else {
NSLog(@"Was NULL");
}
... you have two problems here. Firstly, searchResults1
will never be nil. Regardless of whether the fetch finds any objects, it will return an array object. Instead, you should check the count of the array. Secondly, the %Matches
is a typo. The %
is a formatting control character and will cause the complier to look for a control code e.g. %@
immediately afterward. Try this instead:
if ([searchResults1 count]>0){
NSLog(@"Matches: %i", [searchResults1 count]);
}else {
NSLog(@"No managed objects found");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With