【问题标题】:Apple XCode CoreData SQLite file location keeps movingApple XCode CoreData SQLite 文件位置不断移动
【发布时间】:2020-04-02 23:47:12
【问题描述】:

我正在用 Swift 和 SwiftUI 编写我的第一个 CoreData 应用程序。我有基本的工作并且对此非常满意。我使用 SQLiteStudio 3.2.1 能够独立于我的代码查看数据库。我可以使用 XCode (11.4) 中的“-com.apple.CoreData.SQLDebug 3”和“-com.apple.CoreData.Logging.stderr 1”CoreData 运行时选项轻松找到 *.sqlite 文件。一切正常。

我遇到的问题是 SQLiteStudio 时不时停止显示应用程序在调试时所做的任何更新,并且模拟器中的调试应用程序只看到新条目,而不是数据库中已经存在的条目。我有点困惑,但后来我对 *.sqlite 文件进行了“查找”,发现它时不时地切换到一个新文件。我想如果我停止并启动模拟器,它可能会创建一个新文件,但是当我尝试它时它并没有创建一个新文件。我想也许如果我关闭 XCode 并重新启动它会创建一个新文件,但这也没有创建一个新文件。它似乎几乎是随机创建一个新文件。

有谁知道是什么原因导致 XCode 为其正在运行的应用程序生成一个新的 *.sqlite 文件?我想将其关闭,以便它继续使用相同的 *.sqlite 文件,这将使测试更容易。

感谢任何和所有的想法。

【问题讨论】:

  • 不确定您的应用是什么,但如果您更改模拟器和/或在模拟器中卸载并重新安装您的应用,就会发生这种情况
  • 谢谢 zaitsman。你知道是否有办法覆盖这种行为?这似乎会使测试变得有点复杂。我注意到即使我关闭模拟器并重新启动它,它也不会创建一个新的数据库,有时即使我只是让 XCode 和模拟器运行几天,它似乎也会创建一个新的数据库。它不经常这样做,也许每两周一次,但我无法确定任何模式。什么是模拟器中的卸载?
  • 将其视为在设备上重新安装应用程序。如果应用程序是新的(例如,新的应用程序 ID,或者您删除了它,或者模拟器是一个新盒子(想想 XCode 升级/操作系统版本更改)),那么您基本上处于应用程序的不同安装中。你想如何防止它?
  • 这一切都说得通。它只是使使用 SQLite 等外部工具跟踪数据库变得困难。每次在模拟器上重新安装应用程序时,您都必须在 SQLite 中找到该文件并连接到它。不是什么可怕的事情,只是乏味。感谢您的帮助,我想我的答案是我需要更加小心和控制应用程序在模拟器中重新安装的时间!再次感谢您的建议。
  • 或者,你知道,你可以只写一个 bash 文件来观察模拟器文件夹,每次创建新文件夹时,用你的 SQLiteStudio 打开它...

标签: swift xcode sqlite swiftui


【解决方案1】:

所以我找到了解决问题的方法。事实证明,Core Data 创建了一个 URL,它将在创建 NSPersistentContainer 对象时存储 DB 并将其存储在它保留的 NSPersistentStoreDescription 对象数组中。我假设 Core Data 中有代码从许多属性中构造该 URL,包括在 XCode 下运行的目标模拟器。因此,如果模拟器发生变化,或者应用程序被卸载并重新安装在模拟器中,当 XCode 开始新的应用程序时,它会看到模拟器的新位置,并将其用作 Core Data 的 URL 对象的基本路径用于定位 SQLite DB。

因此,因为我想在构建和调试应用程序时将数据库固定在固定位置,所以我只是用指向我想要的位置的 URL 对象覆盖了容器内数组中 NSPersistentStoreDescription 对象中的 URL 对象DB登陆。我将其包装在#if DEBUG 条件编译中,这样我就不会不小心将该代码留在生产构建中。

为此,我在持久容器的延迟加载创建中将代码添加到 AppDelegate(由 XCode 生成的代码)。代码长这样(唯一的新代码是条件编译中的代码);

lazy var persistentContainer: NSPersistentContainer = {

let container = NSPersistentContainer(name: "TestDB")

#if DEBUG
  container.persistentStoreDescriptions[0].url = 
     URL(fileURLWithPath: "/Users/justme/Documents/code/data/TestDB.sqlite")
#endif

我已经对此进行了测试,它似乎工作正常。如果数据库不存在,则在该路径上创建它,如果它已经存在,则使用它。我可以卸载应用程序然后重新启动,它仍然使用相同的数据库实例。

我希望这对其他人有所帮助,并感谢“zaitsman”为我提供了一些背景知识,帮助我制定了完成这项工作的道路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多