问题
I can't see any problem with these line of code. Why can't it parse?
[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %1$@) || "
"(userId CONTAINS[cd] %1$@) || "
"(firstname CONTAINS[cd] %1$@) || "
"(lastname CONTAINS[cd] %1$@)", searchString]"
The Log doesn't help either.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "(username CONTAINS[cd] %1$@) || (userId CONTAINS[cd] %1$@) || (firstname CONTAINS[cd] %1$@) || (lastname CONTAINS[cd] %1$@)"'
Edit 1:
Okay, it seems like predicateWithFormat doesn't understand "%1$@". I switch it to
[... predicateWithFormat:[NSString stringWithFormat:...]] // (same format as above)
It passed the line. But, the next problem is:
self.filteredUserList = [self.userList filteredArrayUsingPredicate:predicate];
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: the entity User is not key value coding-compliant for the key "a".'
"a" is the keyword I entered in the searchTextBox. WUT?
I printed out the predicate in the debug console, looks nothing wrong:
username CONTAINS[cd] a OR userId CONTAINS[cd] a OR firstname CONTAINS[cd] a OR lastname CONTAINS[cd] a
Edit 2:
Okay, problem solved with this super ugly code:
[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %@) || "
"(userId CONTAINS[cd] %@) || "
"(firstname CONTAINS[cd] %@) || "
"(lastname CONTAINS[cd] %@)", searchString, searchString, searchString, searchString];
What if I want to expand the search field in the future? I've got to add more parameters? more ", searchString, searchString, searchString"?
SOLVED
Thanks to Ewan and Bannings, giving 2 options to my question. I tested both of them, and they worked liek a charm. Can someone explain the different between those two, and in which case should I use which option?
** NOTE **
Bannings' answer is alright, until my search string contains a single quote '
, then the app crash. So I think use Ewan's one is better.
回答1:
You can do this:
[[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] $str) || ..."] predicateWithSubstitutionVariables:@{@"str": searchString}];
回答2:
Try change %1$@
to '%1$@'
:
NSString *formatString = [NSString stringWithFormat:@"(username CONTAINS[cd] '%1$@') || (userId CONTAINS[cd] '%1$@') || (firstname CONTAINS[cd] '%1$@') || (lastname CONTAINS[cd] '%1$@')", searchString];
NSPredicate *predicate = [NSPredicate predicateWithFormat:formatString];
回答3:
You need to add the string for each variable, if you use 5 %@ you need to apply either the same searchString value or another value filling for that %@
[NSPredicate predicateWithFormat:@"(username CONTAINS[cd] %1$@) ||
(userId CONTAINS[cd] %1$@) || (firstname CONTAINS[cd] %1$@) ||
(lastname CONTAINS[cd] %1$@)", searchString1,searchString2,searchString3,searchString4]
来源:https://stackoverflow.com/questions/31128837/nspredicate-unable-to-parse-format-string