将 CoreStore SQLiteStore 移动到另一个位置

Move CoreStore SQLiteStore to another location

在我使用 CoreStore 5.3 的应用程序中,我试图将我的本地 sqlite 存储移动到另一个位置,以便能够从应用程序扩展访问数据库。使用 FileManager.default.moveItem(at: oldURL, to: newURL) 为当前 3 个文件(MyApp.sqlite、MyApp.sqlite-wal 和 MyApp.sqlite-shm)移动文件时工作正常,我只是不认为这样做是个好主意...

if FileManager.default.fileExists(atPath: oldFileURL.path) {
    do {
        try FileManager.default.moveItem(at: oldFileURL, to: newFileURL)
        try FileManager.default.moveItem(at: oldJournalingURL, to: journalingURL)
        try FileManager.default.moveItem(at: oldSharedMemoryURL, to: sharedMemoryURL)
    } catch let error {
        // error handling ...
    }
}

我知道 NSPersistentStoreCoordinator 上有一个功能可以 migratePersistentStore (https://developer.apple.com/documentation/coredata/nspersistentstorecoordinator/1468927-migratepersistentstore)

因此您通常会这样做,例如:

if let persistentStore = persistentStoreCoordinator.persistentStores.first {
    do {
        try persistentStoreCoordinator.migratePersistentStore(persistentStore, to: newFileURL, options: nil, withType: NSSQLiteStoreType)
    } catch {
        print("error")
    }
}

...因为这也会移动所有关联的文件。

但是,显然这个方法并没有暴露在CoreStore中。 除了 persistentStoreCoordinator 是 DataStack 的内部 属性 之外,访问它的唯一方法是通过 unsafeContext(),在 dataStack 已经设置之后,但这会导致更多的麻烦,因为上下文然后尝试做执行 save(),因为持久存储已被移动,它不会工作。

有没有其他方法可以用 CoreStore 做到这一点?

您说得对,目前无法从 CoreStore 执行此操作。部分原因是真的没有办法安全地做到这一点。在移动文件之前,CoreStore 无法知道 none 提到的文件正在其他地方使用。

对于 SQLite 存储,移动您提到的 3 个文件可能是最简单的实现。如果您对二进制属性使用 "External Storage",您还需要移动名为 .<sqlitename>_SUPPORT 的文件夹。因此,如果您的 sqlite 文件名为 mydata.sqlite,则此文件夹将被命名为 .mydata_SUPPORT.

我的建议是为您的商店创建一个专用文件夹,并只将与 SQLite 相关的文件放在那里。因此,下次您要移动目录时,只需移动文件夹本身即可。