Alex Alex - 10 days ago 13x
iOS Question

CoreData NSFetchRequest error NSInvalidArgumentException in Swift 3

After updating my project to latest swift syntax (Swift 3) I'm getting an error on performing CoreData fetch request. So the app worked for many months and now it's broken.

So this is how I perform my fetch request.

let requestSavedLevel = NSFetchRequest<NSFetchRequestResult>(entityName: "LevelEntity")
let levelNamePredicate = NSPredicate(format: "levelName = %@", levelName)
requestSavedLevel.predicate = levelNamePredicate

do {
let results = try userDataStack.context.fetch(requestSavedLevel) as? [LevelEntity]
if (results?.count)! > 0 {
self.savedLevel = results?.first!

return results?.first!
catch {
print("\n Error on \(#function): \(error)")

The error occurs on a line

let results = try userDataStack.context.fetch (requestSavedLevel) as? [LevelEntity]

and it immediately takes me to AppDelegate and shows Thread 1: signal SIGABRT

The console prints out message:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSDictionary initWithObjects:forKeys:]: count of objects (0) differs from count of keys (9)'

I have no clue what happened and why the code is no longer working. I've seen other questions about CoreData problems in Swift 3 but that didn't help.

* EDIT *

I tried to find what causes the error and I found next.
My NSManagedObject has these properties
`extension MyEntity {

@nonobjc public class func fetchRequest() -> NSFetchRequest< MyEntity > {
return NSFetchRequest< MyEntity >(entityName: "MyEntity");

@NSManaged public var horizontal: NSObject?
@NSManaged public var name: String?
@NSManaged public var shapes: NSObject?


I want to save the next data to core data:
var horizontal: [[Int]]
var name: String
var shapes: [Int:Shape]

And I do it like this:

let entity = NSEntityDescription.insertNewObject(forEntityName: "MyEntity", into: userDataStack.context) as! MyEntity = name
entity.horizontal = horizontal as NSObject
entity.shapes = shapes as NSObject


However, error occurs when I try to save the last part which is
entity.shapes = shapes as NSObject

Shape is a custom class, subclass of NSObject.

So what I get when I try to fetch data from Core Data, is that count of objects (0) differs from count of keys (9)'.

Again, everything has worked great for many month until I updated project to Swift 3.

I tried to use NSArchiver to archive shapes and then assign it to entity.shapes as NSObject, and it works, but if it the only solution then I have to update a lot of code.

Any suggestions why this is not working?


So I solved it. The problem was in decoding my custom NSObject subclass.

aDecoder.decodeObject(forKey: "number") as? Int

decodeObject didn't return me an integer value, but I discovered that decodeInteger method does it.

aDecoder.decodeInteger(forKey: "column")

However, decodeInteger method sometimes caused a crash as well, so I ended up with the next condition:

var n = aDecoder.decodeObject(forKey: "number") as? Int
if n == nil {
    n = aDecoder.decodeInteger(forKey: "number")