NSPredicate predicateWithFormat:argumentArray: Only Evaluating First Argument - ios

I'm having some trouble using NSPredicate predicateWithFormat:argumentArray:. In this example, serverIDList is array of strings. Results is an array of NSManagedObjects with an attribute named "flid" which is a string.
NSMutableString *predicateString = [[NSMutableString alloc] init];
[predicateString appendString:#"(flid IN %#)"];
[results filterUsingPredicate:[NSPredicate predicateWithFormat:predicateString argumentArray:serverIDList]];
The problem is that [NSPredicate predicateWithFormat:predicateString argumentArray:serverIDList] evaluates to "flid IN '2155'", which is only the first value of the array serverIDList. I can't seem to get the predicate to evaluate the entire array. Is there something missing here?
Thanks!

[NSPredicate predicateWithFormat:#"(flid IN %#)" argumentArray:serverIDList]
is equivalent to
[NSPredicate predicateWithFormat:#"(flid IN %#)", id1, id2, ..., idN]
where id1, ..., idN are the elements of the array serverIDList.
That should explain why only the first element is evaluated.
What you probably want is
[NSPredicate predicateWithFormat:#"(flid IN %#)", serverIDList]
Remark: I would recomment not to create predicates as strings first. The chances for
quoting or escaping errors are quite high. Use only predicateWithFormat with a
constant format string. If you have to combine predicates dynamically at runtime,
use NSCompoundPredicate.

Related

How to set predicate for a string attribute holding integer value in core data

How to set predicate for a string attribute holding integer value in core data to get the in-between values in integer.
I am using compound predicate for multiple conditions and a piece of code follows..
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"rating >= %# AND rating <= %#",ratingFrom.text,ratingTo.text];
[compoundPredicateArray addObject: categoryPredicate ];
"rating" attribute is of type string in database. I need to get the rating between the given range in the ratingFrom & ratingTo textfields.
"1" to "10" should fetch all ratings in between 1 to 10.how can I achieve this, without changing the attribute type to number.
Any help appreciated..Thanks
i am not confirm but try this
convert your values in NSString and put this code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"string CONTAINS[c] %#",searchText];
Ideally you should change this attribute to be a number rather than a string. But if that's not possible, the following should force CoreData (or rather SQLite) to treat it as a number:
NSPredicate *categoryPredicate = [NSPredicate predicateWithFormat: #"add:to:(rating,0) >= %d AND add:to:(rating,0) <= %d",ratingFrom.text.intValue,ratingTo.text.intValue];
you can try BETWEEN expression:
BETWEEN The left-hand expression is between, or equal to either of,
the values specified in the right-hand side. The right-hand side is a
two value array (an array is required to specify order) giving upper
and lower bounds. For example, 1 BETWEEN { 0 , 33 }, or $INPUT BETWEEN
{ $LOWER, $UPPER }. In Objective-C, you could create a BETWEEN
predicate as shown in the following example:
So your code should look like this:
NSPredicate *betweenPredicate =
[NSPredicate predicateWithFormat: #"rating BETWEEN %#", #[ratingFrom, ratingTo]];
ratingFrom, ratingTo should be NSNumber instances if rating is NSNumber.

NSPredicate - Return inexact matches

In my app I allow users to search for vehicles by make/model using a textfield keyword search. Here is my predicate:
if (self.keywordSearch.text.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"fields.make CONTAINS[cd] %# OR fields.model CONTAINS[cd] %#", self.keywordSearch.text, self.keywordSearch.text];
self.vehicleArray = [[self.vehicleArray filteredArrayUsingPredicate:predicate] mutableCopy];
}
The problem is that if the Vehicle make/model is 'Ford F-150' and the user searches F150, or F 150, the vehicle isn't included in the results. It only returns if they search F-150 or f-150.
Is there a way to make sure these inexact matches are returning?
I suggest using regular expressions for this. You can either use a regular expression literal inside the NSPredicate format (described here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html ) or you can iterate the array manually and use an NSRegularExpression for comparing the strings.

add componentsseparatedbystring into a predicate with core data

i have a String stored in an Entity (core data) i want to use an NSFetchedResultsController to get data.
string format: abc,ba,x,s,d. this is an array of IDs saved as string.
i want to get only entities that contains at least an IDs in that string.
the problem is if i use CONTAIN in the predicate and search for "a" i will get a wrong result.
could you please tel me if it's possible to add something like "componentsseparatedbystring" in a predicate so i can iterate and use "in"in the result or if there's an other solution, thanks.
You can use the "MATCHES" operator in a predicate, which does a
regular expression match:
NSString *searchID = #"a";
NSString *pattern = [NSString stringWithFormat:#"(^|.*,)%#(,.*|$)",
[NSRegularExpression escapedPatternForString:searchID]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID MATCHES %#", pattern];
The pattern (^|.*,)TERM(,.*|$) searches for TERM which is preceded
by either the start of the string or a comma, and followed by the
end of the string or another comma.
First convert your array of ID's into an NSArray:
NSArray *arrayOfIds = [stringOfIds componentsSeparatedByString:#","];
Then use an IN predicate on your fetch:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID IN %#", arrayOfIds];
this assumes your database column is called "ID", and your comma-separated string of ID's is stringOfIds.
finally i will use a dirty solution: we have 4 possibilities:
string format= a
string format= a,..
string format= ..,a
string format= ..,a,..
so the predicate could be:
[NSPredicate predicateWithFormat:#"(ID LIKE %# OR
ID CONTAINS %# OR
ID CONTAINS %# OR
ID ENDSWITH %#)",
searchedID,
[NSString stringWithFormat:#"%#,", searchedID],
[NSString stringWithFormat:#",%#", searchedID],
[NSString stringWithFormat:#",%#,", searchedID]]
but this is a dirty solution, i really want something cleaner.

NSPredicate crash on CONTAINS?

I'm trying to do a simple predicate filter on an array of objects.
The objects in the array have 2 properties, displayValue and value. I am trying to filter based on a search string and I get a crash.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"displayValue CONTAINS[cd] %#", searchString];
NSArray *results = [_data filteredArrayUsingPredicate:pred];
what exactly is incorrect about this format that it causes a Can't use in/contains operator with collection 100 (not a collection) crash?
I was able to reproduce your problem. This happens if the displayValue of one of the objects
is not a NSString, but some different type.
From your error message, I assume that you assigned an NSNumber, for example
obj.displayValue = #100;
somewhere in your code. The "CONTAINS" predicate works only with strings, so you must assign
only string values to the property.
Therefore, you should define the type of the property as
NSString * instead of id, and check the assignments to that property.
If you really need to keep the id type and store different kinds of objects in that property,
then you cannot use the "CONTAINS" operator in the predicate. A direct comparison
with #"displayValue == %#" would work, however.
UPDATE: As a workaround, you could use the description method, which converts any object
to a string, in particular it converts a NSNumber to its string representation. So the following could work:
[NSPredicate predicateWithFormat:#"displayValue.description CONTAINS[cd] %#", searchString];
The drawback is that the exact description format is not documented.
Another solution could be to use a block-based predicate, where you can check the type
of each object and perform the appropriate comparison.

How can I filter UITableView with two predicates in IOS

I have tableView with searchDisplayController. In this TV i have to arrays (first/last names)
I can filter this values by names, using predicate, with this code
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self.firstName beginswith[cd]%#",searchString];
self.filteredAllClients = [AllClients filteredArrayUsingPredicate:predicate];
Can i filter this arrays using two predicates?
For example: I have names (Jack Stone, Mike Rango)
If I`m entering 'J' and i should get filtered array - Jack Stone
But if I'm entering 'R' and i should get filtered area - Mike Rango?
Yes, like this...
NSPredicate *firstNamePredicate = [NSPredicate predicateWithFormat:#"self.firstName beginswith[cd]%#",searchString];
NSPredicate *lastNamePredicate = [NSPredicate predicateWithFormat:#"self.lastName beginswith[cd]%#",searchString];
NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[firstNamePredicate, lastNamePredicate]];
self.filteredAllClients = [AllClients filteredArrayUsingPredicate:compoundPredciate];
This will then show all people whose first names begin with the search OR whose last names begin with the search.
I prefer using this format to using the ORs and ANDs in a single predicate as it makes the overall code more readable.
This can also be used to get the NOT of a predicate.
You can also easily get confused if you have compound predicates built in a single predicate.

Resources