27

I am trying to use NSPredicate in Swift to query Core Data but it throws an EXC_BAD_ACCESS(Code=1, address=0x1) error when trying to run it, what am I doing wrong?

Here is the file where the error happens

class LevelsScreenModel : UIViewController {

func getWord(level: Int, section: Int) -> String
{
    let fetchRequest = NSFetchRequest(entityName: "Words")

    //This is the line where the error happens
    fetchRequest.predicate = NSPredicate(format: "level = %@", level)
    fetchRequest.predicate = NSPredicate(format: "section = %@", section)

    let word = AppDelegate().managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as [Words]

    if(word.count > 1)
    {
        for words in word
        {
            println(words.word)
            return words.word
        }
    }

    return "ERROR"
  }
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
Cesarg2199
  • 569
  • 1
  • 6
  • 18
  • The final error was due to not being able to do "AppDelegate()." to access the managedObjectContext. Instead this code worked for me "var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)" Hope this helps anyone – Cesarg2199 Feb 20 '15 at 16:20

2 Answers2

78

The %@ placeholder in predicate format strings is for Objective-C objects, so you have to wrap the integer into an NSNumber:

fetchRequest.predicate = NSPredicate(format: "level = %@", NSNumber(integer: level))

or use ld instead to format a (long) integer:

fetchRequest.predicate = NSPredicate(format: "level = %ld", level)

Note also that

fetchRequest.predicate = NSPredicate(format: ...)
fetchRequest.predicate = NSPredicate(format: ...)

does not create a compound predicate, the seconds assignment simply overwrites the first. You can use an NSCompoundPredicate:

let p1 = NSPredicate(format: "level = %ld", level)!
let p2 = NSPredicate(format: "section = %ld", section)!
fetchRequest.predicate = NSCompoundPredicate.andPredicateWithSubpredicates([p1, p2])

or simply combine the predicates with "AND":

fetchRequest.predicate = NSPredicate(format: "level = %ld AND section = %ld", level, section)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
-3

Instead of fussing around with format conversions and AND subpredicates, you could use the PredicatePal framework:

fetchRequest.predicate = *(Key("level") == level && Key("section") == section)

Note that you'll need to use == instead of = for equality comparison.

Glen Low
  • 4,379
  • 1
  • 30
  • 36