iOS: NSPredicate doesn't work correct - ios

I try to express the search parameters with predicate:
NSPredicate *predicate=[NSPredicate predicateWithFormat:#"name CONTAINS [cd] %# OR code CONTAINS [cd] %# OR currency CONTAINS [cd] %# AND continent.paid == %#",searchString,searchString,searchString,[NSNumber numberWithBool:YES]];
I try to express search parameters for possible string records ONLY where continent.paid==YES. The problem is that last expression is ignored. The search returns data from continent.paid==NO as well with the correct data. Whats wrong with it?

You have to set parentheses:
[NSPredicate predicateWithFormat:#"(name CONTAINS [cd] %# OR code CONTAINS [cd] %# OR currency CONTAINS [cd] %#) AND continent.paid == %#",
searchString,searchString,searchString,[NSNumber numberWithBool:YES]];
As far as I know, "AND" and "OR" have the same precedence in a predicate, and are evaluated
from left to right. Therefore in your code, the predicate evaluates to true if one
of the "CONTAINS" expressions is true.

Related

are NSPredicate's reserved words case sensitive?

From apple doc:
These two predicates give me same result:
Uppercased SELF:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"SELF.userType != %#", typeStr];
Lowecased SELF:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"self.userType != %#", typeStr];
Are Reserved Words case sensitive?
See Predicate Format String Syntax
"The predicate string parser is whitespace insensitive, case insensitive with respect to keywords, and supports nested parenthetical expressions."

NSPredicate execureFetchRequest not working - possibly due to spaces in string

I am trying to search in CoreData for an object that matches both a recordId and a string name, but it doesn't always find the object.
For example, I an searching for an object with id 1000 and name "The Brown Family" (note the 2 spaces between "The" and "Brown").
If I use:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#") AND (name like[cd] %#)", recordId, name];
with recordId=1000 and name="The Brown Family", the fetch request returns nil.
If I use:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#"), recordId];
with recordId=1000, it finds the object. If I print the object's name property, I get "The Brown Family".
So the object is there with the correct id and name, but my fetchRequest fails.
What am I doing wrong?
You might need to enclose the value in single quotes...
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(recordId == %#) AND (name like[cd] '%#')", recordId, name];
Sorry but I realise what the problem is now! The name I was searching for had a trailing space after it. So I was looking for say "Toby " whereas "Toby" was stored in Coredata.
Sorry for wasting everyone's time.

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.

how to create a predicate in which % work as a string in ios

I am using a Predicate for filtering a NSArray but, when a create Predicate like this
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K contains[c] %# && %K contains[c] %# ",
kUnitUnitcategoryKey,
#"Blood Pressure Diastolic",
kUnitUnitNameKey,
[_txtOxygenSaturationUnit.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
after this "predicate" string is : "unit_category CONTAINS[c] "Blood Pressure Diastolic" AND unit_name CONTAINS[c] "%" "
NSArray *results = [_arrUnitsName filteredArrayUsingPredicate:predicate];
it will return Zero records.
Now, how can i used % as a string.
This is an extremely ugly way to write a somewhat complex predicate. You'll find using NSCompoundPredicates are MUCH easier to manage and modify. Simply create your multiple NSPredicates then use an andPredicate to combine all of your predicates.
What is the best way to build a complex NSCompoundPredicate?
As far as the actual question of how can you use % as a string? Test each predicate individually if you are getting zero results for easier debugging and you'll find the issue much easier.

NSPredicate for Regular Search

I am using NSPredicate for the performing Search as it does on iPhone when we search for any app.
I have say for example 4 keywords
Deccan
New Delhi
Ahmedabad
Salaam Delhi
I have tried creating a predicate with
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'"
It gives me Deccan as output.
But the problem is I want each word starting with d So from the above example I need output as
Deccan, New Delhi, Salaam Delhi but NOT Ahmedabad
Stucked in this issue from hours. tried contains, matches but my bad luck..
Any help towards right path will really be appreciated..
Thanks guys for your responses
Here's what I come up with
NSString *matchString = [NSString stringWithFormat: #".*\\b%#.*",searchText];
NSString *predicateString = #"keyword MATCHES[c] %#";
NSPredicate *predicate =[NSPredicate predicateWithFormat: predicateString, matchString];
There are two way for you
Divide the steing by ' ' and use your NSPredicate *predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'"]
Or, the better way, to use two predicates :
predicate = [NSPredicate predicateWithFormat:#"keyword BEGINSWITH[c] 'd'
OR keyword contains[c] ' d'"]// i mean,'space+d'
So you'll it will satisfy both of possible cases.
Consider "like" and "matches." Note, however, that these are relatively expensive operations, and can take considerable time on large data sets.
In this example, I assume what you want is to match if any space-separated word in starts with "d"
This checks to see if keyword either begins with 'd' or has a sequence with a followed by 'd'
[NSPredicate predicateWithFormat:#"(keyword BEGINSWITH[c] 'd') OR (keyword LIKE[c] '* d')"]
This one uses a regular expression, which is very similar (use the regex that best suites your situation:
[NSPredicate predicateWithFormat:#"keyword MATCHES[c] '^d.*|.*\\sd.*'"]

Resources