Bartłomiej Semańczyk Bartłomiej Semańczyk - 7 months ago 73
Swift Question

"Invalid predicate: nil RHS" for second argument in NSPredicate format

This is my

NSPredicate
:

print(searchTextField.text!)
let predicate = NSPredicate(format: "student.schoolClass.id = %d AND (book.title CONTAINS[cd] %@ OR student.username CONTAINS[cd] %@)", currentSchoolClass.id, searchTextField.text!, searchTextField.text!)


The next thing I do is:

fetchedResultsController.fetchRequest.predicate = predicate
print(fetchedResultsController.fetchRequest.predicate!)
try! fetchedResultsController.performFetch() //here is the crash


The console output is:

j
student.schoolClass.id == 1 AND (book.title CONTAINS[cd] nil OR student.username CONTAINS[cd] "j")


And crash info is:

CRASH: Invalid predicate: nil RHS


Isn't it weird?

Answer

On all current iOS and OS X platforms, the C int is a 32-bit integer, and that is what the %d format expects on the variable argument list. If you pass a 64-bit integer then reading the next variable argument will read the extra 4 zero bytes.

The following table shows which format is for which integer type:

  Format   C type          Swift type
  -----------------------------------
  %d       int             Int32
  %ld      long int        Int
  %lld     long long int   Int64

and similarly for the unsigned types.

Alternatively, convert the integer to a NSNumber object and use the %@ format, this works for integers of all sizes. Example:

let value = 1234
let predicate = NSPredicate(format: "value = %@", value as NSNumber)