5

I give up. I have tried every combination I can imagine to check if a string contains another string. Here's an example of intuitive syntax describing what I want to do:

    NSPredicate* pPredicate = [NSPredicate predicateWithFormat:@"NOT (%K CONTAINS[c] %@)",
NSMetadataItemFSNameKey, 
[NSString stringWithFormat:@"Some String"]];

Regardless of how I shift the NOT around, use the ! operator instead, shift the parentheses or remove them altogether, I always get an exception parsing this expression.

What is wrong with this expression?

EDIT: The exception happens when I call

[pMetadataQuery setPredicate:pPredicate];

and the exception is: * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unknown type of NSComparisonPredicate given to NSMetadataQuery (kMDItemFSName CONTAINS[c] "Some String")'

vargonian
  • 3,064
  • 3
  • 27
  • 36
  • Possible duplicate of this question: http://stackoverflow.com/questions/8580715/nsarray-with-nspredicate-using-not-in – joern Jul 13 '12 at 18:51
  • Can you tell us what the exception is? – Tommy Jul 13 '12 at 18:52
  • joern, I've seen many similar questions but like that one, it doesn't answer my issue. "IN" isn't the same as contains, as it involves sets (as I understand it). @Tommy, I updated the question. I hope that helps. – vargonian Jul 13 '12 at 18:56
  • possible duplicate of [Writing an NSPredicate that returns true if condition is not met](http://stackoverflow.com/questions/1166401/writing-an-nspredicate-that-returns-true-if-condition-is-not-met) – Monolo Jul 14 '12 at 04:15

2 Answers2

11

I had complete success with:

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"NOT (%K CONTAINS[c] %@)",
        @"someKey",
        [NSString stringWithFormat:@"Some String"]];
NSArray *testArray =
    [NSArray arrayWithObjects:
        [NSDictionary dictionaryWithObject:@"This sure is Some String" forKey:@"someKey"],
        [NSDictionary dictionaryWithObject:@"I've nothing to say" forKey:@"someKey"],
        [NSDictionary dictionaryWithObject:@"I don't even have that key" forKey:@"someOtherKey"],
        nil];

NSArray *filteredArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"found %@", filteredArray);

The second two objects of the three in testArray ended up in filteredArray, under OS X v10.7 and iOS v4.3. So the issue isn't the predicate — making this technically a complete answer to the question — it's some sort of restriction in NSMetadataQuery. Sadly I've no experience in that area, but it's certainly the next thing to research.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • Thank you, Tommy. Google produces but one seemingly related result to their being a limitation with NSMetadataQuery, which allegedly was solved by using "IN" instead of "CONTAINS", but that sounds obviously wrong, since the docs are explicit about CONTAINS being for strings and IN being for dictionaries, etc. – vargonian Jul 13 '12 at 19:18
  • I'm marking this as an answer since, though it doesn't resolve my problem, my question was misleading. – vargonian Jul 17 '12 at 00:38
1

Swift 3.0

let predicate = NSPredicate(format: "NOT (%K CONTAINS[c] %@)", "someKey", "Some String")
let testArray: [Any] = [[ "someKey" : "This sure is Some String" ], [ "someKey" : "I've nothing to say" ], [ "someOtherKey" : "I don't even have that key" ]]
let filteredArray: [Any] = testArray.filter { predicate.evaluate(with: $0) }
print("found \(filteredArray)")
Abhishek Jain
  • 4,557
  • 2
  • 32
  • 31