[NSPredicate predicateWithFormat:@"%@ contains %@", column, searchString];
When you use the %@
substitution in a predicate format string, the resulting expression will be a constant value. It sounds like you don't want a constant value; rather, you want the name of an attribute to be interpreted as a key path.
In other words, if you're doing this:
NSString *column = @"name";
NSString *searchString = @"Dave";
NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ contains %@", column, searchString];
That is going to be the equivalent to:
p = [NSPredicate predicateWithFormat:@"'name' contains 'Dave'"];
Which is the same as:
BOOL contains = [@"name rangeOfString:@"Dave"].location != NSNotFound;
// "contains" will ALWAYS be false
// since the string "name" does not contain "Dave"
That's clearly not what you want. You want the equivalent of this:
p = [NSPredicate predicateWithFormat:@"name contains 'Dave'"];
In order to get this, you can't use %@
as the format specifier. You have to use %K
instead. %K
is a specifier unique to predicate format strings, and it means that the substituted string should be interpreted as a key path (i.e., name of a property), and not as a literal string.
So your code should instead be:
NSPredicate *query = [NSPredicate predicateWithFormat:@"%K contains %@", column, searchString];
Using @"%K contains %K"
doesn't work either, because that's the same as:
[NSPredicate predicateWithFormat:@"name contains Dave"]
Which is the same as:
BOOL contains = [[object name] rangeOfString:[object Dave]].location != NSNotFound;