Reputation: 661
I am new to core data.
What I am trying to DO: I am trying to create a cocoatouch framework that has an app to add employee details and display them in a table view. So that i can add this framework to my main project to work independently.
Issues I face: The frame work builds without any error. I have added the core data stack from swift 3 to the framework. But when i run the main project, the moment the framework loads the log displays "Failed to load model named Simple framework", "fetch failed" and "employee must have a valid entity description". The code that I have used in the framework is as shown below :
public class CoreDataStack {
public static let sharedInstance = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "SimpleFramework")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error {
fatalError("Unresolved error \(error), \(error)")
}
})
return container
}()
public func saveContext() {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
}
}
@IBAction func addEmployee(_ sender: Any) {
//To save the data
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let employee = Employee(context: context)
employee.employeeName = nameTextField.text
employee.employeeAge = Int16(ageTextField.text!)!
employee.hasVehicle = hasVehicle.isOn
CoreDataStack.sharedInstance.saveContext()
navigationController!.popViewController(animated: true)
}
@IBAction func addEmployee(_ sender: Any) {
//To save the data
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let employee = Employee(context: context)
employee.employeeName = nameTextField.text
employee.employeeAge = Int16(ageTextField.text!)!
employee.hasVehicle = hasVehicle.isOn
CoreDataStack.sharedInstance.saveContext()
navigationController!.popViewController(animated: true)
}
Upvotes: 45
Views: 27753
Reputation: 441
If you want to use CoreData in your dynamic framework you have to subclass NSPersistentContainer
and use it instead of NSPersistentContainer
.
class PersistentContainer: NSPersistentContainer { }
//...
lazy var container: PersistentContainer = {
let result = PersistentContainer(name: "Your xcdatamodeld file name here")
result.loadPersistentStores { (storeDescription, error) in
if let error = error {
print(error.localizedDescription)
}
}
return result
}()
Upvotes: 6
Reputation: 2232
My problem was at my .podspec file. You should include the xcdatamodeld extension on the pod that you are creating.
s.resources = "myprojectfolder/**/*.{png,jpeg,jpg,storyboard,xib,xcassets,xcdatamodeld}"
Upvotes: 2
Reputation: 1431
I've had this issue, when I had wrong model name - it should be models name, not the projects (see the screen shot)
Upvotes: 134
Reputation: 34983
The string you pass to the NSPersistentContainer initializer:
NSPersistentContainer(name: "CoreData")
needs to match the filename of the data model file in your Xcode project:
CoreData.xcdatamodeld
Upvotes: 12
Reputation: 31
In my case, for some reason the DataModel.xcdatamodeld
became missing from my project workspace.
First I tried creating a new DataModle.xcdatamodeld
and recreating the data model, but the same error occurred. Thats when I realized that the Original DataModel.xcdatamodeld
was still in the root directory. I fixed this by simply right clicking my project in my project navigator, and selecting "Add files to "Project"..."
, then I added my old data model and deleted my new data model. Finally I hard cleaned, ran my project and it fixed the issue.
Upvotes: 2
Reputation: 19602
Explicitly pass the models file name to the Core Data stack for initialization and make sure, it is loaded from the right bundle at the time (test bundle, app bundle...) by using Bundle(for: type(of: self))
:
//...
let momdName = "SimpleFramework" //pass this as a parameter
//...
guard let modelURL = Bundle(for: type(of: self)).url(forResource: momdName, withExtension:"momd") else {
fatalError("Error loading model from bundle")
}
guard let mom = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Error initializing mom from: \(modelURL)")
}
persistentContainer = NSPersistentContainer(name: momdName, managedObjectModel: mom)
//...
Edit:
Also make sure, the SimpleFramework.xcdatamodeld
is added to the used targets Target Membership
:
Upvotes: 61