How to apply a boolean operation in an NSPredicate? - ios

I have the following Search NSPredicate
NSPredicate *searchPredicateTextComponent = [NSPredicate predicateWithFormat:#"(SUBQUERY(entities, $x , ((ANY $x.objects.type LIKE 'text') AND ((ANY $x.objects.desc CONTAINS[c] %#) OR (ANY $x.objects.desc BEGINSWITH[c] %#)))).#count != 0)", [NSString stringWithFormat:#" %#",subString],subString ];
Now I need to block the objects that don't have a boolean combination to be true which is:
i.e. if P = $x.isAllowed, S = $x.shouldByPass then boolean operation P'S == TRUE must be added to the NSPredicate.
Is this possible or feasible?

Related

NSPredicate use array as filter

I'm trying to use an array as a filter to search Core Data. The values that the fetchRequest returns should have an ID that is in the predicate's array.
let arrayOfFavoriteStampIDS = [302,2300,2309]
fetchRequest.predicate = NSPredicate(format: "itemID IN %i", argumentArray: arrayOfFavoriteStampIDS)
Almost
fetchRequest.predicate = NSPredicate(format: "itemID IN %#", arrayOfFavoriteStampIDS)
argumentArray means something else for example
fetchRequest.predicate = NSPredicate(format: "itemID == %i OR itemID == %i OR itemID == %i", argumentArray:arrayOfFavoriteStampIDS)
In this case each item in the array must match one %i placeholder.

iOS: NSPredicate doesn't work correct

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.

NSPredicate format specifiers issue

I use this predicate:
NSPredicate *offencePredicate =
[NSPredicate predicateWithFormat:#"(%# == %#) AND (%# == %d)", kTeamID, self.selectedTeam.teamID, kPlayerZoneID, ZoneIdTypeOffence];
but the predicate is:
"teamID" == 10 AND "playerZoneID" == 3
instead of:
teamID == 10 AND playerZoneID == 3
How can I trim this "" when I use format specifiers for predicating. And the next question is: is this the right solution using form specifiers in predicate. Because I have some API keys that are correspond to my core data entries attributes. So it is ok to use constant string that will allow quite faster changes if I need to change some of these keys, but is it ok to use this constant for predication?
You need to use %K for the keys.
It would look like this:
[NSPredicate predicateWithFormat:#"(%K == %#) AND (%K == %d)", kTeamID, self.selectedTeam.teamID, kPlayerZoneID, ZoneIdTypeOffence];
Use %K.
See this example from the documentation:
NSString *attributeName = #"firstName";
NSString *attributeValue = #"Adam";
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K like %#",
attributeName, attributeValue];
Result:
firstName like "Adam"

NSPredicate Aggregate Operations with NONE

How do I create a predicate that can fetch: all questions does not contain answer.correct = "1".
The following predicate doesn't work if the returned array contain "0" and "1":
[NSPredicate predicateWithFormat:#"NONE answers.correct IN %#", [NSArray arrayWithObject:#"1"]];
Also tried with NOT (ANY ...) : same result
Is this a Bug?
Short answer: To get all objects that do not have any "answer" with "correct == 1", use the following SUBQUERY:
[NSPredicate predicateWithFormat:#"SUBQUERY(answers, $a, $a.correct == 1).#count == 0"]
Explanation: Both predicates
[NSPredicate predicateWithFormat:#"NONE answers.correct == 1"]
[NSPredicate predicateWithFormat:#"NOT (ANY answers.correct == 1)"]
should work (as I understand the NOT and ANY keywords) but they don't.
They return the same result set as
[NSPredicate predicateWithFormat:#"ANY answers.correct != 1"]
as can be seen by setting the launch argument -com.apple.CoreData.SQLDebug 3 and inspecting the SQL select statements.
This seems like a Core Data bug to me. Using the SUBQUERY is a workaround for that problem.

NSPredicate filter based on one to many values

I have 2 entities with a one to many relationship. Category represents my section headers and SubSubCategory represents my rows.
Category
{
name:string
subs<-->>SubCategory
}
SubCategory
{
name:string
numbervalue:NSNumber
}
Currently I can use NSPredicate to filter my sections based on name.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name==%#",#"anamevalue"];
Now I want to further filter this predicate to only return categories that have a Subcategory with a subvalue == 1.
How can I filter the Category entity based on the values in its one to many children?
I tried something like this but its no good.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name==%# AND subs.numbervalue==%#",#"anamevalue",1];
I'll do a predicate like the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %# AND ANY subs.numbervalue == %#)", #"anamevalue", [NSNumber numberWithInt:1]];
The ANY is a predicate modifier that returns true only if there is at least one object in subs collection for which the comparison returns true.
The same result could be done by means of SUBQUERY.
Hope it helps.
The syntax in your predicate is wrong. You are passing an integer value as a string.
Your predicate should be
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name==%# AND subs.numbervalue==%i",#"anamevalue",1]
Other than that it looks correct.

Resources