如何在框架内使用Core Data的ManagedObjectModel?

flo*_*hei 27 frameworks core-data nsbundle ios nsmanagedobjectmodel

我正在尝试将我的某个应用程序的特定部分迁移到框架中,以便我可以在我的应用程序本身和其中一个新的iOS 8小部件中使用它.这部分是处理Core Data中所有数据的部分.将所有内容移到并访问它是非常简单的.我只是momd在那里访问我的文件时遇到问题.

在创建时NSManagedObjectModel我仍然尝试加载momdApple的代码模板中所示:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Run Code Online (Sandbox Code Playgroud)

不幸的是,在使用此错误访问Core Data堆栈时modelURL停留nil并因此MyApp崩溃:

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'
Run Code Online (Sandbox Code Playgroud)

那么,在使用Core Data在框架内部工作时,采用这种方法的正确方法是什么?

Jon*_*han 23

对于弗洛赫的问题,我有点迟了,但希望这可以帮助其他任何徘徊的人.有可能让这个工作无需执行脚本fu来复制资源!

默认情况下,Apple的Core Data模板可以为您提供以下内容:

lazy var managedObjectModel: NSManagedObjectModel = {
  let modelURL = NSBundle.mainBundle().URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
  return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
Run Code Online (Sandbox Code Playgroud)

这会将您的Core Data资源从主捆绑中加载出来.这里的关键是:如果在框架中加载Core Data模型,则.momd文件位于该框架的bundle中.所以我们只是这样做:

lazy var managedObjectModel: NSManagedObjectModel = {
    let sexyFrameworkBundleIdentifier = "com.heybaby.xxx"
    let customKitBundle = NSBundle(identifier: sexyFrameworkBundleIdentifier)!
    let modelURL = customKitBundle.URLForResource("MyCuteCoreDataModel", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
Run Code Online (Sandbox Code Playgroud)

这应该可以帮助你正常运转.

图片来源:https://www.andrewcbancroft.com/2015/08/25/sharing-a-core-data-model-with-a-swift-framework/

  • 这绝对应该是公认的答案,谢谢@Jonathan Zhan (3认同)

小智 13

您需要拖动xcdatamodeld文件并将其放入Build Phases中 编译使用该框架的目标的源.然后当目标运行时,它的[NSBundle mainBundle]将包含模型(momd文件).


小智 6

@Ric Santos几乎就在那里.我认为你只需要把它变成"妈妈"的延伸,而不是"妈妈",然后就会运行.

lazy var managedObjectModel: NSManagedObjectModel = {
    let modelURL = NSBundle(forClass: self.dynamicType.self).URLForResource(self.dataModelName, withExtension: "mom")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
Run Code Online (Sandbox Code Playgroud)


and*_*der 0

我假设您只需要数据模型。

如果是这样,我发现以下始终是将数据模型文件从一个项目复制到另一个项目的最成功的方法......

  1. .xcdatamodeld删除驻留在目标项目中的任何当前文件副本。

  2. 关闭 Xcode。

    使用 Finder(或 cmd 行);

  3. 选择包含原始.xcdatamodeld文件的 Xcode 项目文件夹。

  4. 制作原始文件的副本.xcdatamodeld

  5. 将原始文件的副本.xcdatamodeld移至目标项目。

    然后...

  6. 打开 Xcode。

  7. 使用菜单命令“将文件添加到>您的项目<”,找到原始文件的副本并将其添加.xcdatamodeld到您的项目中。

  8. 使用项目导航器重命名原始.xcdatamodeld文件(如有必要)。

  9. “构建并运行”您的目标项目。

这有帮助吗?