I\'ve built a static library that makes heavy use of the Core Data framework. I can successfully use the library in my external project, but ONLY if I include the .xcdatamod
Swift 2 version for Sascha's answer:
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.
var allBundles = NSMutableSet()
allBundles.addObjectsFromArray(NSBundle.allBundles())
allBundles.addObjectsFromArray(NSBundle.allFrameworks())
let model = NSManagedObjectModel.mergedModelFromBundles(allBundles.allObjects as? [NSBundle])
return model!
}()
i have some library with coredata too. i have found this template for manage a framework with embed ressources
it's really simple to use on a new project ( more difficult to apply on existing ) but for framewoks build, it's really cool :-)
https://github.com/kstenerud/iOS-Universal-Framework
Prairiedogg's answer is a little outdated, here's a tutorial on doing this in Xcode 5: http://bharathnagarajrao.wordpress.com/2014/02/14/working-with-core-data-in-a-static-library/
Note that instead of using xcdatamodel/mom file you can also create your model in code (especially if you have a simple model) and this way you won't need to create an additional bundle for resources. Here is a simple example with one table that contains two attributes:
- (NSManagedObjectModel *)coreDataModel
{
NSManagedObjectModel *model = [NSManagedObjectModel new];
NSEntityDescription *eventEntity = [NSEntityDescription new];
eventEntity.name = @"EventEntity";
eventEntity.managedObjectClassName = @"EventEntity";
NSAttributeDescription *dateAttribute = [NSAttributeDescription new];
dateAttribute.name = @"date";
dateAttribute.attributeType = NSDateAttributeType;
dateAttribute.optional = NO;
NSAttributeDescription *typeAttribute = [NSAttributeDescription new];
typeAttribute.name = @"type";
typeAttribute.attributeType = NSStringAttributeType;
typeAttribute.optional = NO;
eventEntity.properties = @[dateAttribute, typeAttribute];
model.entities = @[eventEntity];
return model;
}
Here is a tutorial about creating model from code: https://www.cocoanetics.com/2012/04/creating-a-coredata-model-in-code/
Also based on this approach I created a small and easy to use library that might fit your needs called LSMiniDB so you can check it also.
Also in my case I had warnings such as "warning: dynamic accessors failed to find @property implementation..." on the console while using properties of NSManagedObject subclasses. I was able to fix that by moving those properties to a class interface/implementation instead of having them in a category in a separate file (currently xcode by default is generating this code splited into separate files ClassName+CoreDataClass and ClassName+CoreDataProperties with a class and a category for each subclass).
I also created my own static library that uses Core Data. Besides the static library I have a another bundle target in the project where I have a Copy Bundle Resources item, that copies some images and things like that into the bundle and a Compile Sources build phase, where I am compiling the xcdatamodel.
The final bundle will contain all the necessary files. In your main project that relies on the static library you have to include that bundle as well. Your main project will now have access to the mom file that is needed to use core data.
To use core data with the mom from the bundle you have to create a merged managed object model in your code (it might be the main project has some core data model as well):
- (NSManagedObjectModel *) mergedManagedObjectModel
{
if (!mergedManagedObjectModel)
{
NSMutableSet *allBundles = [[[NSMutableSet alloc] init] autorelease];
[allBundles addObjectsFromArray: [NSBundle allBundles]];
[allBundles addObjectsFromArray: [NSBundle allFrameworks]];
mergedManagedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: [allBundles allObjects]] retain];
}
return mergedManagedObjectModel;
}
By just including the bundle you will not have to give out the xcdatamodel, only the compiled mom file needs to be included.
Sascha Konietzke's solution works well, but there is one important caveat that needs to be provided for it to work. The bundle containing the model needs to be loaded first, otherwise it will not be included in the array and merged in the MOM.
In his case he has probably already accessed resources from the bundle therefore the bundle was already loaded prior to this code being executed.