Swift4:在两个核心数据存储之间切换

Posted

技术标签:

【中文标题】Swift4:在两个核心数据存储之间切换【英文标题】:Swift4: Switching between two Core Data stores 【发布时间】:2018-01-27 03:03:19 【问题描述】:

我需要两个不同的 CoreData 数据库存储,具体取决于我的应用程序运行的模式。它只需要在应用程序第一次运行时切换。

理想情况下,这将使用 persistentContainer 进行设置:

lazy var persistentContainer: NSPersistentContainer = 

    let container = NSPersistentContainer(name: "myApp")
    container.loadPersistentStores(completionHandler:  (storeDescription, error) in
        if let error = error as NSError? 
        
            fatalError("Unresolved error \(error), \(error.userInfo)")
        
    )

我基本上只需要找到这样的命令:

if mode == 1

    storeName = "MyStore1.sqlite"

else

    storeName = "MyStore2.sqlite"

container.useStore(storeName)

【问题讨论】:

【参考方案1】:

当您使用init(name:) 初始化持久化容器时,该名称用于定位模型和持久化存储。来自the docs:

默认情况下,提供的名称值用于命名持久存储,并用于查找要与 NSPersistentContainer 对象一起使用的 NSManagedObjectModel 对象的名称。

但是您可以使用另一个初始化程序init(name:, managedObjectModel:),它允许您为模型和商店指定单独的名称。来自the docs:

默认情况下,提供的容器名称值用作与容器关联的持久存储的名称。传入 NSManagedObjectModel 对象会覆盖通过提供的名称值查找模型。

因此,您只需在初始化持久容器时指定正确的名称和 managedObjectModel 参数即可实现您想要的。

【讨论】:

【参考方案2】:

你在正确的轨道上。概括地说,一个典型的配置将包括一个NSManagedObjectContext,它需要一个NSPersistentStoreCoordinator,而后者又需要一个NSManagedObjectModel。如果您希望在前端和持久存储之间有一个中间步骤,则上下文可以在其上方有另一个上下文。

无论哪种方式,您都有几个选择(可能还有更多):

    将另一家商店添加到您的 NSPersistentStoreCoordinator(请参阅 this answer) 如果您还希望每个商店有两个单独的模型,请创建两个不同的NSManagedObjectContext 实例,每个实例都有自己的NSPersistentStoreCoordinatorNSManagedObjectModel

选项 #2 在代码中管理起来有点笨拙,所以如果您只担心数据的物理存储位置,我会选择选项 #1。否则,您可能希望创建某种上下文管理器来正确监督每个上下文(您也可以将mode == 1 / model == 2 逻辑放在这里)以确保它们不会踩到对方的脚趾。

【讨论】:

以上是关于Swift4:在两个核心数据存储之间切换的主要内容,如果未能解决你的问题,请参考以下文章

在应用程序之间共享核心数据存储

使用 fetched 属性的核心数据跨存储查询

在 Core Data 存储之间切换

两个日期之间实体属性的核心数据总和

根据传递给存储过程的参数在两个游标之间切换

如何在 sqlite 核心数据文件之间正确切换?