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?
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 .
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.
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.
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.
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.
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)")
// }
// }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With