I've got a single string substitution working with NSPredicate but returning core data records that contain either StringA or StringB doesn't seem to be something I can figure out. I want something like this:
let filter = NSPredicate(format: ("%K = %#", "type", "StringA") OR ("%K = %#", "type", "StringB"))
But of course that doesn't work. Help?
You have to specify a format string,
followed by a comma-separated list of arguments to substitute into the format:
let filter = NSPredicate(format:"%K = %# OR %K = %#", "type", "StringA", "type", "StringB")
If the keys are not reserved words and do not contain special characters then you
can specify them directly in the format string:
let filter = NSPredicate(format:"type = %# OR type = %#", "StringA", "StringB")
Related
hello I am working on swift. I need to know how can I find results which matches the exact string. Here's my code
let userID: String = String(sender.tag)
// Create a Predicate with mapping to trip_id
let filterByRequest: NSPredicate = NSPredicate(format: "%K.%K CONTAINS[c] %#", "ProductRequest", "user_id", userID)
// Filter your main array with predicate, resulting array will have filtered objects
let filteredArray: [AnyObject] = self.array.filteredArrayUsingPredicate(filterByRequest)
The problem is If user id is 69 it shows results of users whose id is 69, 6, and 9.
I googled but I find some answers closed to my question but they were all in objective C.
Use MATCHES in predicate as following :
let filterByRequest: NSPredicate = NSPredicate(format: "%K.%K MATCHES %#", "ProductRequest", "user_id", userID)
Hope it helps..
To test for exact equality, simply use == instead of CONTAINS:
NSPredicate(format: "%K.%K == %#", ...)
This can also be combined with [c] for case-insensitive equality:
NSPredicate(format: "%K.%K ==[c] %#", ...)
In the twitter api, the id_str is like this: "572581876033982465".
Right now I want to use NSPredicate to filter the tweets, and the current format is like this:
NSPredicate(format: "idStr > %#", self.maxId!)
Both idStr and self.maxId are type of String. And it crashes with error message: "Operator type 2 not supported for string type".
I think it means that I should cast both of them to number value.
I tried this:
let predicate = NSPredicate(format: "[idStr intValue] > %#", self.maxId!.toInt()!)
But it crashes with error:
Unable to parse the format string "[idStr intValue] > %#
How to cast the id_str in the format?
Have you tried this:
let id_str = "572581876033982465"
let id_num = id_str.toInt()!
var predicate = NSPredicate(format: "id_num > %#", self.maxId!.toInt()!)
I am trying to write a predicate to compare two keys in a cloud kit database. All the documentation I've been able to find only allows you to compare one key against a set value. Is there a way to write a predicate in swift to compare two keys?
The closest I've been able to come up with is:
let pred = NSPredicate(format: "%K == %K", "keyA", "keyB")!
but that keeps crashing on me.
use %# on R.H.S side insted of %k like this..
%# is a var arg substitution for an object value—often a string, number, or date.
%K is a var arg substitution for a key path.
let pred = (NSPredicate(format: "%K == %#", "keyA", "keyB")!)
Are you really trying to compare two keys? Or are you trying to compare the value associated with two keys? The difference between %# and %K in a predicate is that %# will be appropriately escaped, while %K won't be.
So:
NSPredicate(format:"value = %#", "Fred") // yields 'value = "Fred"'
While:
NSPredicate(format:"value = %K", "Fred") // yields 'value = Fred'
You want to use %K when you're passing an key name in as a parameter to the predicate, while you want to use '%#' if you're passing in a value.
From your example, title, and question, it's tough to figure out what you're actually trying to do, if you a predicate that insures that the value of two fields/keys is the same, you want to use
NSPredicate(format:"%K = %K", "key1", "key2")
as you're doing.
If you're trying to check that a particular key has a particular value, use:
NSPredicate(format:"%K = %#", "key1", "value1")
The code you've given, in isolation, executes just fine, where and what exactly is crashing, give us a bit more context.
With the further information that you're wanting to filter for records containing the same value in two different fields, it appears that CloudKit doesn't support field OP field only field OP constant Given that, the best work around I can suggest is:
let predicate = NSPredicate(format: "(gender1 = \"male\" AND gender2 = \"male\") OR (gender1 = \"female\" AND gender2 = \"female\")")
I am trying to create a function that searches through my core data stack and return the amount of messages for a desired key/value.
Here is my code:
NSFetchRequest *messagesCountRequest = [NSFetchRequest fetchRequestWithEntityName:#"Message"];
NSEntityDescription *messageCountModel = [NSEntityDescription entityForName:#"Message" inManagedObjectContext:_mainManagedObjectContext];
[messagesCountRequest setEntity:messageCountModel];
NSPredicate *messageCountPredicate = [NSPredicate predicateWithFormat:#"%# == %#", key, value];
[messagesCountRequest setPredicate:messageCountPredicate];
count = (int)[_mainManagedObjectContext countForFetchRequest:messagesCountRequest error:nil];
The problem is that it returns 0 every time. I have located the source of the problem. When have a static key, the predicate looks like this.
key == "value"
When I pass through a dynamic key, it looks like this
"key" == "value"
So the problem appears to be the first set of double quotes around the key that is placed by passing a NSString to the predicate. How would I fix this?
EDIT: For clarity, I need it to be like the first case, that is the one that works.
To substitute a key in the predicate string, you have to use %K, not %#:
[NSPredicate predicateWithFormat:#"%K == %#", key, value];
From the Predicate Format String Syntax documentation:
%# is a var arg substitution for an object value—often a string, number, or date.
%K is a var arg substitution for a key path.
let predicate = NSPredicate(format: "SELF[%#] CONTAINS %#",key,value)
This worked for me
I want to filter out empty records, but I am not able to remove the records which has no data but a series of space..
I have a Entity A with attribute "name" . I want to query all those objects of Entity A which has some text value for attribute name and not "series of space",In other words I need to incorporate this in the query -->
[name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet].length!=0
But all I could was check the length of string INCLUDING the whitespace which is not right.
I am using-->
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"name!=' ' or name.length!=0 "];
Your suggetions are welcome.
you can trim the string and check for the lenght of the string like this:
NSString *trimmedString = [aRecordString stringByTrimmingCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:#" "]]];
if (trimmedString.lenght > 0) {
// the string if valid or at least is not just a spaces string
}
else {
// the string is not valid or was just a spaces string
}
so if you want to apply this check in a predicate you can use a predicate with block:
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
// do your checks here and return TRUE or FALSE if the ovject match your criteria
}];
If you're trying to remove objects where a specific string attribute contains only spaces, use a regex-based predicate, and then delete whatever objects you find.
A fetch with a predicate like this would find all of those objects:
NSPredicate *reqPredicate = [NSPredicate predicateWithFormat:#"attributeName matches ' +'"];
Once found, use -[NSManagedObjectContext deleteObject:] to delete the resulting objects.