Reputation: 4796
I set up a DatabaseApplicationService that
This all works fine, as it seems.
lazy var persistentContainer: NSPersistentCloudKitContainer = {
// Ensure that we have the required path.
pathHandler.ensurePersistentStorePath()
#if DEBUG
// get the store description
guard let description = container.persistentStoreDescriptions.first
else {
fatalError("Could not retrieve a persistent store description.")
}
// initialize the CloudKit schema
try? container.initializeCloudKitSchema(options: NSPersistentCloudKitContainerSchemaInitializationOptions.dryRun)
#endif
let local = NSPersistentStoreDescription(url: pathHandler.persistentLocalStoreURL)
local.configuration = "Local"
let cloud = NSPersistentStoreDescription(url: pathHandler.persistentCloudStoreURL)
cloud.configuration = "Cloud"
cloud.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.com.innoreq.HappyFreelancer")
container.persistentStoreDescriptions = [ local, cloud ]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
In the SceneDelegate
, the environment gets the NSManagedObjectContext injected:
let contentView = ContentView().environment(\.managedObjectContext, databaseService.context)
In the view's model, the environment is asked for the context:
@Environment(\.managedObjectContext) var managedObjectContext: NSManagedObjectContext
Now, when fetching data from the context:
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "EWork")
do {
return try managedObjectContext.execute(fetchRequest) as! [IsTimedAndTagged]
} catch {
fatalError("Failed to fetch EWork")
}
this error is thrown at runtime:
2020-01-23 16:34:05.981483+0100 XY[14121:20859222] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSPersistentStoreCoordinator for searching for entity name 'EWork''
When checking the service's coordinator, it is not nil. Is there any explanation for that strange effect?
Upvotes: 5
Views: 3712
Reputation: 4727
I had the same error when I tried to create a new NSManagedObject in a child context but the child context didn't have a persistent store assigned.
The code produces the error:
let childContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) // The context doesn't have related persistent store
let newObject = NSEntityDescription.insertNewObject(forEntityName: entityName, into: childContext) // The error occurred when trying to find the entity from a nil persistent store
Adding the persistent store to the child context fixed the error.
@Environment(\.managedObjectContext) var moc
let childContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
childContext.persistentStoreCoordinator = moc.persistentStoreCoordinator // add persistent store to the context
let newObject = NSEntityDescription.insertNewObject(forEntityName: entityName, into: childContext)
Reference: https://blog.csdn.net/weixin_40200876/article/details/87866492
Hope it helps :)
Upvotes: 1
Reputation: 1129
For those who are using Swift5 and doesn't have Appdelegate in there and trying to create NFSRequest queries.
You might be missing the persistent store and so creating your own custom store might work. Cause that was my issue.
Creating your own PersistentContainer class:
import SwiftUI
import CoreData
@main
struct TestApp: App {
let context = PersistentCloudKitContainer.persistentContainer.viewContext
var body: some Scene {
WindowGroup {
ContentView().environment(\.managedObjectContext, context)
}
}
}
Then your custom class like this:
import CoreData
public class PersistentCloudKitContainer {
// MARK: - Define Constants / Variables
public static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: - Initializer
private init() {}
// MARK: - Core Data stack
public static var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "Model")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
// MARK: - Core Data Saving support
public static func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
Hope it helps someone like me, who might end up here looking for answers!
Upvotes: 2