Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Core Data's ManagedObjectModel inside a framework?

I'm trying to migrate a specific part of one of my apps into a framework so that I can use it in my app itself and in one of those fancy new iOS 8 widgets. This part is the one that handles all my data in Core Data. It's pretty straight forward to move everything over and to access it. I'm just having trouble accessing my momd file in there.

When creating the NSManagedObjectModel I still try to load the momd as illustrated in Apple's code templates:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Unfortunately, modelURL stays nil and thus MyApp crashes when accessing the Core Data stack with this error:

2014-08-01 22:39:56.885 MyApp[81375:7417914] Cannot create an NSPersistentStoreCoordinator with a nil model
2014-08-01 22:39:56.903 MyApp[81375:7417914] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'

So, what's the right way to do this when working inside a framework with Core Data?

like image 295
flohei Avatar asked Aug 01 '14 20:08

flohei


People also ask

Can we use Core Data managed objects from background thread?

Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.

Can we have multiple managed object context in Core Data?

Most apps need just a single managed object context. The default configuration in most Core Data apps is a single managed object context associated with the main queue. Multiple managed object contexts make your apps harder to debug; it's not something you'd use in every app, in every situation.

What is managed object in Core Data?

A managed object context represents a single object space, or scratch pad, in a Core Data application. A managed object context is an instance of NSManagedObjectContext . Its primary responsibility is to manage a collection of managed objects.


2 Answers

I'm a bit late for flohei's issue, but hopefully this helps anybody else who wanders by. It is possible to get this to work without having to perform script-fu to copy resources around!

By default Apple's Core Data template gives you something like this:

lazy var managedObjectModel: NSManagedObjectModel = {   let modelURL = NSBundle.mainBundle().URLForResource("MyCoreDataModel", withExtension: "momd")!   return NSManagedObjectModel(contentsOfURL: modelURL)! }() 

That would load your Core Data resources out of the main bundle. The key thing here is: if the Core Data model is loaded in a framework, the .momd file is in that framework's bundle. So instead we just do this:

lazy var managedObjectModel: NSManagedObjectModel = {     let frameworkBundleIdentifier = "com.myorg.myframework"     let customKitBundle = NSBundle(identifier: frameworkBundleIdentifier)!     let modelURL = customKitBundle.URLForResource("MyCoreDataModel", withExtension: "momd")!     return NSManagedObjectModel(contentsOfURL: modelURL)! }() 

That should get you up and running.

Credit: https://www.andrewcbancroft.com/2015/08/25/sharing-a-core-data-model-with-a-swift-framework/

like image 54
Jonathan Zhan Avatar answered Sep 17 '22 13:09

Jonathan Zhan


You need to drag the xcdatamodeld file and drop it in the Build Phases | Compile Sources for the targets that use the framework. Then when the target runs its [NSBundle mainBundle] will contain the model (momd file).

like image 24
user3771857 Avatar answered Sep 21 '22 13:09

user3771857