0

I am using NSPredicate to filter the contents of an NSArray of NSDictionary objects. Nothing crazy. I want to check three different values in the dictionary for the same search string. Here is the string I am passing to [NSPredicate predicateWithFormat:]:

($ECInstanceLabel CONTAINS[c] filterMe) OR (SubLabel1 CONTAINS[c] filterMe) OR (SubLabel2 CONTAINS[c] filterMe)

When I execute this, a valid instance of a new NSPredicate is created, but when I do [NSArray filteredArrayUsingPredicate:], the application throws an exception.

The exception is:

'NSInvalidArgumentException', reason: 'Can't get value for 'ECInstanceLabel' in bindings { }.'

I think part of the problem is that my format string specifies that the first dictionary key value is $ECInstanceLabel but somehow the $ is getting escaped. I have tried manually escaping this character but then the program crashes when I try to create the predicate, so I don't think the $ symbol is recognized as an escapable character.

Any ideas or something obvious I may be missing?

Thanks in advance.

itslittlejohn
  • 1,808
  • 3
  • 20
  • 33

1 Answers1

3

$var is used in predicates for variables that can be substituted later. If you have a key containing $ or other special characters then use the %K expansion:

 [NSPredicate predicateWithFormat:@"(%K CONTAINS[c] %@) OR (SubLabel1 CONTAINS[c] %@) OR (SubLabel2 CONTAINS[c] %@)",
          @"$ECInstanceLabel", searchTerm, searchTerm, searchTerm]

And use the %@ format for the search term instead of writing it inline, to avoid errors if the search term contains special characters.

Of course you can use %@ for all keys, but in this case you need it only for the first key that contains special characters.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • I was not aware of the %K expansion option. Can you give an example of how to write this with three CONTAINS statements that only require one searchTerm parameter? – itslittlejohn Feb 20 '14 at 18:39
  • @itslittlejohn: See updated answer, you just have to repeat the arguments. – Martin R Feb 20 '14 at 18:43
  • Okay, fair enough. The reason I was passing the string inline was so that I could avoid passing the search term multiple times. NSString stringWithFormat handles this nicely. – itslittlejohn Feb 20 '14 at 18:45
  • 1
    @itslittlejohn: But that will cause errors as soon as the search term contains quotation marks. (I would never mix `stringWithFormat` and `predicateWithFormat`.) – Martin R Feb 20 '14 at 18:46