gpt4 book ai didi

ios - 将核心数据数据库从一个应用程序迁移到另一个应用程序

转载 作者:行者123 更新时间:2023-11-28 06:12:53 26 4
gpt4 key购买 nike

我有一个 Core Data 数据库,我希望在首次启动时无需加载所有数据即可预填充该数据库。我试图通过创建第二个应用程序来完成此操作,该应用程序负责加载并将 SQL 数据库从该应用程序复制到新应用程序。最初我尝试简单地从第二个应用程序复制 .sqlite 文件并将文件复制到第一个应用程序中,如下所示:

lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "GeoPointDB")

let seededData: String = "GeoPointDB"
var persistentStoreDescriptions: NSPersistentStoreDescription

let storeUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!

if !FileManager.default.fileExists(atPath: (storeUrl.path)) {
let seededDataUrl = Bundle.main.url(forResource: seededData, withExtension: "sqlite")
try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl)

}

container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error {

fatalError("Unresolved error \(error),")
}
})

return container

}()

但是,这给了我一条错误消息,提示“无法打开数据库文件”。研究了一下我发现了这篇文章: https://developer.apple.com/library/content/qa/qa1809/_index.html

因此,我回到第二个应用程序并尝试使用以下代码正确导出数据库:

let documents = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!   
do {
try context.persistentStoreCoordinator!.migratePersistentStore(context.persistentStoreCoordinator!.persistentStores.first!, to: documents, options: nil, withType: NSSQLiteStoreType)
print("Managed to save database file")
} catch let error as NSError {
print("Failed to save DB: \(error)")
}

但是当我这样做时,我得到了与尝试将复制的数据库加载到第一个应用程序时完全相同的导出错误:“无法打开数据库文件”。关于我做错了什么或如何使用 iOS 10/11 和 Swift 3/4 执行数据库迁移的任何提示?

一些可能有用的附加信息:

  • 这两个应用程序都具有来自 Xcode 在项目创建时的“使用核心数据”选项的标准 CoreData 代码
  • 第一个应用中的 CoreData 模型(.xcdatamodeld 文件)是从第二个应用复制的,以确保没有不一致
  • 我能够毫无问题地从第二个应用程序的数据库中添加和获取数据

最佳答案

最后我设法找到了一个可行的解决方案。我仍然没有弄清楚如何成功导出数据库,但由于我只会为每个应用程序更新执行一次此迁移(或不太频繁)我可以手动复制数据并通过简单地测试之前验证数据库是否损坏提交到 App Store。

关于导入数据库的代码,我最终使用的是:

lazy var persistentContainer: NSPersistentContainer = {
let databaseName = "GeoPointDB"

let container = NSPersistentContainer(name: databaseName)

var persistentStoreDescriptions: NSPersistentStoreDescription

let storeUrl = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!.appendingPathComponent(databaseName + ".sqlite")
let storeUrlFolder = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!

if !FileManager.default.fileExists(atPath: (storeUrl.path)) {
let seededDataUrl = Bundle.main.url(forResource: databaseName, withExtension: "sqlite")
let seededDataUrl2 = Bundle.main.url(forResource: databaseName, withExtension: "sqlite-shm")
let seededDataUrl3 = Bundle.main.url(forResource: databaseName, withExtension: "sqlite-wal")

try! FileManager.default.copyItem(at: seededDataUrl!, to: storeUrl)
try! FileManager.default.copyItem(at: seededDataUrl2!, to: storeUrlFolder.appendingPathComponent(databaseName + ".sqlite-shm"))
try! FileManager.default.copyItem(at: seededDataUrl3!, to: storeUrlFolder.appendingPathComponent(databaseName + ".sqlite-wal"))

}

container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: storeUrl)]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error {

fatalError("Unresolved error \(error),")
}
})

return container
}()

我基本上改变的两件事是确保 NSPersistantStoreDescription 直接指向 SQL 文件(而不是上面的目录),并且我复制了所有三个文件(. sqlite, .sqlite-shm.sqlite-wal) 到文档文件夹。

关于ios - 将核心数据数据库从一个应用程序迁移到另一个应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46013862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com