CoreData in Swift Packages

I am having issues loading my model from a Swift Package with the following structure:

| Package.swift
| Sources
| - | SamplePackage
| - | - Core
| - | - | - SamplePackageDataStack.swift
| - | - | - DataModel.xcdatamodeld
| - | - | - | - Model.xcdatamodel ( <- is this new? )

As mentioned, I am not required to list the xcdatamodeld as a resource in my Package manifest.

When trying to load the model in the main app, I am getting
CoreData: error:  Failed to load model named DataModel

Code:

In my swift Package:
Code Block swift
public class SamplePackageDataStack: NSObject {
    public static let shared = SamplePackageDataStack()
    private override init() {}
    public lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()
    /// The managed object context associated with the main queue. (read-only)
    public var context: NSManagedObjectContext {
        return self.persistentContainer.viewContext
    }
    public func saveContext () {
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }
}



Main App:

Code Block swift
import SamplePackage
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var container = SamplePackageDataStack.shared.persistentContainer
        print(container)
}
}


My code is a little older, but the principles should be the same. Here's how I created an NSManagedObjectModel:

Code Block
lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional.
    // It is a fatal error for the application not to be able to find and load its model.
    let bundle = Bundle.module
    let modelURL = bundle.url(forResource: self.managedModelRootName, withExtension: self.managedModelExtension)!
    return NSManagedObjectModel(contentsOf: modelURL)!
}()


The key is I had to find the reference to it myself using the bundle that contains the module. To find the bundle I used Bundle.module which may be new to things this year. I found out about it from Insert link text here.

For your code, which looks like it is based off of newer template code, you'll have to find the proper load point. The key is to use the right bundle, though.
I just looked at it. Bundle.main is generated. It essentially boils down to Bundle(for: BundleFinder.self) where BundleFinder.self is the name of the generated file. That's really close to what I had in there before all this. It looks for the resources in three places so you have flexibility on where to put your resources:

Code Block
        let candidates = [
            // Bundle should be present here when the package is linked into an App.
            Bundle.main.resourceURL,
            // Bundle should be present here when the package is linked into a framework.
            Bundle(for: BundleFinder.self).resourceURL,
            // For command-line tools.
            Bundle.main.bundleURL,
        ]

@endres How would you load the container to context from a Bundle though? I do see you can load the object that way
Hi,
This post helped me so I figured I'd post a working example of the core data model that I am successfully using in a new Swift Package. This code below is from the lazy var persistentContainer:

Code Block
  let bundle = Bundle.module
  let modelURL = bundle.url(forResource: "ModelName", withExtension: ".momd")!
  let model = NSManagedObjectModel(contentsOf: modelURL)!
  let container = NSPersistentCloudKitContainer(name: "ModelName", managedObjectModel: model)


You can make the model a lazy var.

I call it from the host app below:

Code Block
    NavigationLink(destination: GenericListCDView()
        .environment(\.managedObjectContext,ModelCDStack.shared.context)
        , label: {
        Text("My List")
    })


Hope this helps.
CoreData in Swift Packages
 
 
Q