Ashiq Sulaiman
Ashiq Sulaiman

Reputation: 661

Core data: Failed to load model

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)
}

This is a screenshot of the console log.

Upvotes: 45

Views: 27753

Answers (6)

Levan Karanadze
Levan Karanadze

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

mourodrigo
mourodrigo

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

Dmitriy Yerchick
Dmitriy Yerchick

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)enter image description here

Upvotes: 134

pkamb
pkamb

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

Alec Michel
Alec Michel

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

shallowThought
shallowThought

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

Related Questions