[NSPredicate predicateWithFormat:@"%@ contains %@", column, searchString];
When you use the %@ substitution in the predicate format string, the resulting expression will be a constant value . It seems you do not want a constant value; rather, you want the attribute name to be interpreted as the key path.
In other words, if you do this:
NSString *column = @"name"; NSString *searchString = @"Dave"; NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ contains %@", column, searchString];
This will be equivalent to:
p = [NSPredicate predicateWithFormat:@"'name' contains 'Dave'"];
This is the same as:
BOOL contains = [@"name rangeOfString:@"Dave"].location != NSNotFound; // "contains" will ALWAYS be false // since the string "name" does not contain "Dave"
This is clearly not what you want. You want the equivalent of this:
p = [NSPredicate predicateWithFormat:@"name contains 'Dave'"];
To get this, you cannot use %@ as a format specifier. You should use %K instead. %K is a specifier unique to predicate format strings, and this means that the replaced string should be interpreted as the key path (that is, the name of the property), and not as a literal string.
So your code should be:
NSPredicate *query = [NSPredicate predicateWithFormat:@"%K contains %@", column, searchString];
Using @"%K contains %K" does not work either, because it is the same as:
[NSPredicate predicateWithFormat:@"name contains Dave"]
This is the same as:
BOOL contains = [[object name] rangeOfString:[object Dave]].location != NSNotFound;