Search code examples
iphonecore-dataswift3ios10

Core data fetchRequest gives executeFetchRequest:error: <null> is not a valid NSFetchRequest


I while ago, I updated one of my apps to iOS 10, and I got it working, and since then I've been using it on my phone (installed without removing old app, where new app replaced old one). Now when I've removed the app from my iPhone, and reinstalled the same one it doesn't work.

I've been trying out to solve this problem by different changes and trying to get an understanding on what is going wrong. I also searched on Google and here on Stack Overflow without any success.

The error I get is this:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'executeFetchRequest:error: is not a valid NSFetchRequest.'

Here is my code, and it is performed very early in the app launch:

        let allItemFetchRequest: NSFetchRequest<Item>
    if #available(iOS 10.0, *) {
        allItemFetchRequest = Item.fetchRequest() as! NSFetchRequest<Item>
    } else {
        // Fallback on earlier versions
        allItemFetchRequest = NSFetchRequest(entityName:"Item")
    }

    do {
        let searchItems = try self.managedObjectContext.fetch(allItemFetchRequest)

        if searchItems.count == 0 {
            return true
        }
    } catch let error as NSError {
        print("\(#file):\(#function): \(error)::\(error.userInfo)")
    } catch {
        print("\(String(describing: self)):\(#function): fatal error")
        // Remove before release
        fatalError()
    }

And it's always crashing at the let searchItems = try self.persistentContainer.viewContext.fetch(allItemFetchRequest) row.

The code is used to check if there is any data since previous launch, and if not, I add a some data to Core Data SQLite DB from a file. So, previously if worked because I had data in the DB from a pre-iOS 10 version app, I think.

If I bypass this functionality and imports data into DB by using let newItem = (NSEntityDescription.insertNewObject(forEntityName: "Item", into: self.managedObjectContext) as! Item) it does import all my data correctly. To me it feels like it is the first fetch request I do that fails - inserts seems to work ok.

I'm using an migrated version of the Apple-original Core data stack functions inside the AppDelegate.

What am I doing wrong? Any help or hints would be appreciated!


Solution

  • Edit

    I got It working when I simplified fetchRequest's declaration. Instead of using:

    let allItemFetchRequest: NSFetchRequest<Item>
    if #available(iOS 10.0, *) {
        allItemFetchRequest = Item.fetchRequest() as! NSFetchRequest<Item>
    } else {
        // Fallback on earlier versions
        allItemFetchRequest = NSFetchRequest(entityName:"Item")
    }
    

    Try using:

    let entityName = String(describing: Item.self)
    let request = NSFetchRequest<Item>(entityName: entityName)
    

    Cheers!