swift NSPredicate compare string - ios

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()!)

Related

NSPredicate crash after swift 3 migration

after migration to swift3, I have an issue that cannot fix
let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "id == %#", id)
my App crashes on second line, bad access, no reason. types are right, no log, nothing, just bad access. any suggestions?
Found a reason, predicate is wrong, cause id is Int64 type, have no idea what kind of predicate I need for this version of swift
The %# format expect a Foundation object as argument, compare
"Predicate Format String Syntax" in the "Predicate Programming Guide".
You can bridge the Int64 to NSNumber:
let id = Int64.max
let predicate = NSPredicate(format: "id == %#", id as NSNumber)
print(predicate) // id == 9223372036854775807
or change the format to "long long":
let id = Int64.max
let predicate = NSPredicate(format: "id == %lld", id)
print(predicate) // id == 9223372036854775807
Bridging all number types to NSNumber is possible as of Swift 3.0.1 (Xcode 8.1) with the implementation of
SE-0139 Bridge Numeric Types to NSNumber and Cocoa Structs to NSValue.

How to query for String AND NSDate property?

I am facing an odd error with my code:
if let date = self.messages.last?.date {
let newMessages = self.realm.objects(Message).filter("chatId == '\(self.chatId!)' AND date > \(date)")
}
This outputs the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "chatId = 'oSgUGWH9fWURmBh5NQZK2POpxdI3yEdl7PrPzAU33l7cVFIpzR38otF3' AND date > 2016-07-17 10:56:07 +0000"'
What am I doing wrong?
EDIT:
Using NSPredicate it works:
let predicate = NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date)
newMessages = self.realm.objects(Message).filter(predicate)
But why doesn't the first solution work?
If you want to filter an array using a predicate, you need to pass a predicate and not just a string literal as the argument, and also use the method filteredArrayUsingPredicate(_:).
Why "chatId == '\(self.chatId!)' AND date > \(date)" doesn't work is that the compiler interprets this as a string literal - and not a predicate as you've created in your other example:
NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date)
The fix is to either instantiate an NSPredicate as you've done in your edit, and pass that value to filteredArrayUsingPredicate(:_) or just move the instantiation to inside the method:
newMessages = self.realm.objects(Message).filteredArrayUsingPredicate(NSPredicate(format: "chatId = %# AND date > %#", self.chatId!, date))
If you want to use this method, the array needs to be an NSArray, and the objects in the array need to be KVC compliant, so you're better off in Swift with using the filter(_:) method as such:
let newMessages = self.realm.objects(Message).filter({ $0.chatId == self.chatId! && $0.date.compare(date) == NSComparisonResult.OrderedDescending })

NSPredicate Exact Match with String

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] %#", ...)

NSPredicate substring in string

I want to show all items where value1 contains value2. I tried this:
let fetchRequest = NSFetchRequest(entityName: "Product")
fetchRequest.predicate = NSPredicate(format: "value1 CONTAINS[cd] value2")
value1, value2 - current object values, it is not variables
But i got error:
Unable to parse the format string
Why it doesn't allow me to do this ?
Try to use this predicate:
let predicate = NSPredicate(format: "value1 CONTAINS[cd] %#", value2)
As were investigated during communication with developer. Issue is in data that is saved to the database. In his case data is saved with quotes ("") and NSPredicate(format: "value1 CONTAINS[cd] %#", value2) is working with errors due to that issue.

swift NSPredicate logical OR

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")

Resources