Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve: "NSPersistentStoreCoordinator has no persistent stores"?

I'm following this tutorial exactly, which adds CoreData to an existing app: https://www.youtube.com/watch?v=WcQkBYu86h8

When I get to the seedPerson() moc.save(), the app crashes with this error:

CoreData: error: Illegal attempt to save to a file that was never opened. "This NSPersistentStoreCoordinator has no persistent stores (unknown). It cannot perform a save operation.". No last error recorded.

The NSManagedSubclass has been added.

The DataController is wired up and I can step into it. It isn't until the save() that things go wrong. Any idea what I might have left out to cause this error?

like image 886
4thSpace Avatar asked Oct 25 '15 16:10

4thSpace


People also ask

Why do we need multiple persistent store?

A separate persistent store is a much better solution in both cases. Each persistent store has its own characteristics — it can be read-only, stored as binary or SQLite or in-memory (on OS X, an XML backing store is also available), or your own implementation of an NSIncrementalStore .

What are persistent stores available in Core Data?

Core Data provides four store types—SQLite, Binary, XML, and In-Memory (the XML store is not available on iOS); these are described in Persistent Store Features.

What is persistent store in iOS?

Data persistence means storing any type of data to disk so that the same data can be retrieved without being altered when the user opens the app next time. We are going to describe all the ways to store data locally in iOS apps.

What is NSPersistentStoreCoordinator in iOS?

A persistent store coordinator is an instance of NSPersistentStoreCoordinator . It has a reference to a managed object model that describes the entities in the store or stores it manages. The coordinator is the central object in a Core Data stack.


2 Answers

Unfortunately, that video uses some code from Apple's website, and that code example is flawed. The main flaw is that it caches the MOC before the persistent store has been added to the MOC. Thus, if the creation of the store fails at all, the managed object context will be initialized with a persistent store coordinator that has no store.

You need use the debugger and step through the code that creates the PSC (the DataController.init method) and see why the failure happens. If you cut/paste the same way as in that example, then maybe you also forgot to change the name of your model when instantiating the model.

In any event, the most likely cause is that some initialization code in that function failed, and you are subsequently going happily along with a core data stack that has no stores.

like image 22
Jody Hagins Avatar answered Sep 19 '22 07:09

Jody Hagins


I also followed that YouTube tutorial and had the same problem. I just removed the background thread block that adds the persistent store and it worked. Here's my DataController:

import UIKit
import CoreData

class WellbetDataController: NSObject {
    var managedObjectContext: NSManagedObjectContext

    override init() {
        // This resource is the same name as your xcdatamodeld contained in your project.
        guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else {
            fatalError("Error loading model from bundle")
        }

        // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
        guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else {
            fatalError("Error initializing mom from: \(modelURL)")
        }

        let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
        self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        self.managedObjectContext.persistentStoreCoordinator = psc

        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        let docURL = urls[urls.endIndex-1]
        /* The directory the application uses to store the Core Data store file.
        This code uses a file named "DataModel.sqlite" in the application's documents directory.
        */
        let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
        do {
            try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
        } catch {
            fatalError("Error migrating store: \(error)")
        }



//        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)) {
//            let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
//            let docURL = urls[urls.endIndex-1]
//            /* The directory the application uses to store the Core Data store file.
//            This code uses a file named "DataModel.sqlite" in the application's documents directory.
//            */
//            let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
//            do {
//                try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
//            } catch {
//                fatalError("Error migrating store: \(error)")
//            }
//        }
    }
}
like image 112
jaytrixz Avatar answered Sep 21 '22 07:09

jaytrixz