core data in a static library for the iPhone

后端 未结 8 1170
不知归路
不知归路 2020-11-28 02:07

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

相关标签:
8条回答
  • 2020-11-28 02:39

    Sascha's answer got me on the right track. Merging a compiled .mom file from a static library into the .mom file from a host project was relatively simple. Here's a trivial example:

    1. Create a new XCode Static Library project called MyStaticLibrary

    2. Create an .xcdatamodel file in MyStaticLibrary called MyStaticLibraryModels.xcdatamodel, add some Entitys, then generate the headers and implementations. When you build the MyStaticLibrary target, you'll generate a libMyStaticLibrary.a binary file, but it won't include the compiled .mom file. For that we have to create a bundle.

    3. Create a new build target of type Loadable Bundle, found under MacOS X > Cocoa, let's call the new Target MyStaticLibraryModels.

    4. Drag MyStaticLibraryModels.xcdatamodel into the Compile Sources build phase of the MyStaticLibraryModels Target. When you build the MyStaticLibraryModels Target, you will generate a file called MyStaticLibraryModels.bundle and it will contain the compiled NSManagedObjectModel file, MyStaticLibraryModels.mom.

    5. After building both the MyStaticLibrary and MyStaticLibraryModels Targets, drag libMyStaticLibrary.a (along with any associated Model header files) and MyStaticLibraryModels.bundle into your host project, MyAwesomeApp.

    6. MyAwesomeApp uses CoreData, has it's own .xcdatamodel file which will get compiled into a .mom file during its own build process. We want to merge this .mom file with the one we imported in MyStaticLibraryModels.bundle. Somewhere in the MyAwesomeApp project, there is a method that returns MyAwesomeApps NSManagedObjectModel. The Apple generated template for this method looks like this:

    ...

    - (NSManagedObjectModel *)managedObjectModel {
      if (managedObjectModel_ != nil) {
        return managedObjectModel_;
      }
      NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
      managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
      return managedObjectModel_;
    }
    

    We will alter this to merge and return BOTH of our NSManagedObjectModels, MyAwesomApps and MyStaticLibraryModels, as a single, combined NSManagedObjectModel like so:

    - (NSManagedObjectModel *)managedObjectModel {
      if (managedObjectModel_ != nil) {
        return managedObjectModel_;
      }
    
      NSMutableArray *allManagedObjectModels = [[NSMutableArray alloc] init];
    
      NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
      NSManagedObjectModel *projectManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
      [allManagedObjectModels addObject:projectManagedObjectModel];
      [projectManagedObjectModel release];
    
      NSString *staticLibraryBundlePath = [[NSBundle mainBundle] pathForResource:@"MyStaticLibraryModels" ofType:@"bundle"];
      NSURL *staticLibraryMOMURL = [[NSBundle bundleWithPath:staticLibraryBundlePath] URLForResource:@"MyStaticLibraryModels" withExtension:@"mom"];
      NSManagedObjectModel *staticLibraryMOM = [[NSManagedObjectModel alloc] initWithContentsOfURL:staticLibraryMOMURL];
      [allManagedObjectModels addObject:staticLibraryMOM];
      [staticLibraryMOM release];
    
      managedObjectModel_ = [NSManagedObjectModel modelByMergingModels:allManagedObjectModels];
      [allManagedObjectModels release];
    
      return managedObjectModel_;
    }
    

    This will return the merged NSManagedObjectModel with the Entitys from both MyAwesomeApp and MyStaticLibrary.

    0 讨论(0)
  • 2020-11-28 02:39

    No, the limitation on using non-Apple frameworks in an iPhone app really changes the dependency game relative to OS X. Most iPhone "frameworks" (e.g. Google's toolbox for Mac, Core Plot, etc.) actually recommend that you include the source in your main application project rather than linking a product (i.e. a static library). I think the community consensus is that, on iPhone, it's OK to expect consumers of your framework to have to do a little "manual" work to use your library. In your case, this is including the xcdatamodel file in the main project. As with most of Objective-C, tell your users not to make use of the implementation details and leave it at that.

    0 讨论(0)
提交回复
热议问题