NSPredicate format specifiers issue - ios

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"

Related

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.

Filter Between NSDates with NSPredicate

A simplified version of my coredata model looks like this
I'm trying to filter a set of assets that meet the following criteria "type"== "DIVIDEND_TYPE" and the "date" falls between "startDate" and "endDate".
My predicate looks like this
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:
#"ANY transactions.type == %# AND ANY transactions.date >= %# AND ANY transactions.date <= %#", DIVIDEND_TYPE, startDate, endDate];
NSSet *filteredSet = [self.portfolio.assets filteredSetUsingPredicate:myPredicate];
This predicate seems to respect the startDate and type, but not the endDate. The filteredSet always includes assets that contain transactions that have dates beyond the endDate.
What I'm I doing wrong?
The conditions get tested independently for each ANY clause, so if an Asset has any transactions of the right type, and any transactions with date after startDate ,etc, - but it could be a different transaction that meets each test. Use SUBQUERY instead: it allows you to test several attributes of each transaction:
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:#"SUBQUERY(transactions, $T, $T.type == %# AND $T.date >= %# AND $T.date <= %#).#count > 0", DIVIDEND_TYPE, startDate, endDate];

How to apply a boolean operation in an NSPredicate?

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?

NSPredicate Format String with unexpected result

I am learning NSPredicate and I have an example with problem.
NSArray * array = #[#{#"name":#"KudoCC"}, #{#"name":#"123"}] ;
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"name == '%#'", #123] ;
NSArray * result = [array filteredArrayUsingPredicate:predicate] ;
The parameter here is #123, it is NSNumber type. I think it works the same as #"name == '123'", but the result is nil, which I expected as #{#"name":#"123"}.
Can somebody tell me why? Thank you in advance.
The document here said,
If you use variable substitution using %# (such as firstName like %#), the quotation marks are added for you automatically.
Quotation marks should be avoided in common cases. If you use something like #"%K == '%#'", you are actually comparing the key with #"%#". Only if you have an array like #[#{#"%#": #"KudoCC"}], you need this way.

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.

Resources