NSPredicate crash after swift 3 migration - ios

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.

Related

NSPredicate format issue

My Entity Office have set of File entities. Each File has uuid property. I need to fetch offices where we have any file where UUID is not in set of Strings
I tried to use
let predicate = NSPredicate(format: "NOT (ALL files.uuid IN %#)", uuidSet)
let predicate = NSPredicate(format: "ANY files.uuid NOT IN %#", uuidSet)
let predicate = NSPredicate(format: "ANY NOT files.uuid IN %#", uuidSet)
I always get the error like
exception 'NSInvalidArgumentException', reason: 'Unsupported predicate NOT ALL files.uuid IN {"C0DF0E67-ED8A-4D3B-87A1-E4E7B86967AA"}'
Is there a way to write this Predicate properly? Because right now I only see the solution to load all offices and then iterate through every item.

can´t understand fetchRequest.predicate

I´ve a quite "simple" predicate for a NSFetchRequest:
guard let kategorie = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Kategorien else {
return
}
let fetchRequest = NSFetchRequest(entityName: "Details")
fetchRequest.predicate = NSPredicate(format: "kategorie == %i", kategorie.katid!)
do {
let results = try self.managedObjectContext.executeFetchRequest(fetchRequest) as! [Details]
...
The content of the sqllite-"table" is
the content of the variables are
So from
fetchRequest.predicate = NSPredicate(format: "kategorie == %i", kategorie.katid!)
i get the Predicate
kategorie == 18
while
kategorie.katid is 1
I can´t understand it :-(
Any help???
That's really strange, but you can just do:
NSPredicate(format: "kategorie = \(kategorie.katid!)")
And then you don't need to worry about whether you need a %i, or a %ld, or a %#, etc...
katid is an (optional) NSNumber, and what happens in your case
is that the (lower 32-bit of the) address of the object is taken as an integer.
The correct format
specifier is %# (for instances of NSObject subclasses):
NSPredicate(format: "kategorie == %#", kategorie.katid!)
Alternatively, convert the object to an integer:
NSPredicate(format: "kategorie == %d", kategorie.katid!.intValue)
Of course, forced unwrapping should be avoided, e.g.
NSPredicate(format: "kategorie == %d", kategorie.katid?.intValue ?? 0)
Using string interpolation in the format string (as suggested by
#Gargoyle) is another solution in this special case of numbers,
but not generally: If you interpolate a string then any percent
character will be interpreted as a format specifier and that leads
to unexpected output or crashes. Also single or double quotes will
lead to problems because these have a special meaning in predicate
format strings.

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 compare string

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

Resources