当SwiftData中@Attribute(.unique)字段,存在重复数据时可能引起应用的崩溃。
因此,需要通过DB Browser for SQLite工具进一步管理SwiftData中的数据,以便解决类似的数据问题。
查找数据库所在的文件夹
首先,我们需要找到模拟器的对应路径,Devices 目录通常在 ~/Library/Developer/CoreSimulator/Devices。在该目录下,你会看到一组文件夹,每个文件夹名就是一个设备的 UUID。
~/Library/Developer/CoreSimulator/Devices
鼠标点击桌面,按Command + Shift + G快捷键,打开文件路径输入框:
在 Devices 目录的每个 UUID 文件夹中,都有一个名为 device.plist 的文件。这个文件存储了该设备的详细信息,包括设备名称(如 iPhone 14、iPad Pro)、操作系统版本和状态(是否已启动等)。
进入到Devices文件夹后,双击并打开device_set.plist文件,它包含所有模拟器的设备信息。可以打开这个文件,搜索设备 UUID,以查找到相关设备的详细信息(如设备名称、操作系统版本等)。
根据模拟器的型号找到对应的设备Key,然后复制Value值。
在文件夹中搜索对应的Value值文件夹。
在设备UUID文件夹下,打开data 文件夹。该文件夹包含了模拟器应用的沙盒文件结构。
Containers 文件夹下有两个子目录:Data 和 Bundle。
进入 Data 文件夹,这里存储了各个应用的数据,包括数据库文件。
在 Data 文件夹下,进入 Application 文件夹。这里面会有多个文件夹,每个文件夹代表一个应用,名称为不同的 UUID。
要找到你的应用对应的文件夹,可以通过最近修改的文件夹。
双击并打开最新的修改文件夹。
在文件夹的目录中,导航到Library文件夹,一般情况下,数据库文件存储在 Application/UUID/Library/Application Support 或 Application/UUID/Library 目录下。
SQL数据库文件介绍
这里可以看到三个SQLite数据库的文件。
1、default.store:
这是数据库的主文件,存储了所有的表结构和基础数据内容。
数据库的主要数据都存放在这个文件中。
2、default.store-shm(Shared Memory):
这是共享内存文件,它是 SQLite 在 WAL(Write-Ahead Logging)模式下用来加速读取的文件。
-shm 文件可以让数据库在不同进程或线程间共享信息,以提高并发性能。
3、default.store-wal(Write-Ahead Log):
这是写入日志文件,它记录了还未写入到主数据库文件(即 default.store)中的更改。
在 WAL 模式下,数据首先写入这个日志文件,之后在适当的时候再写入主数据库文件。
这个机制提高了数据的写入性能和安全性,防止数据丢失。
下载数据库工具
我们需要选择一个数据库浏览工具打开对应的数据库文件:
DB Browser for SQLite(免费,功能丰富,适合常规操作)
SQLiteFlow(macOS 专用,支持 iOS 模拟器数据库文件)
TablePlus(跨平台工具,支持 SQLite 及其他数据库类型)
我这里使用的是第一个DB Browser for SQLite应用,下载方式为打开官网,找到Download下载按钮,选择macOS的下载方式。
这里我推荐第二种brew下载,因为第一种下载方式一直断断续续的。
我们通过brew工具,在终端中输入下载命令:
brew install db-browser-for-sqlite
下载完成后,就可以在启动台页面中找到DB Browser for SQLite应用。
双击打开DB Browser for SQLite应用。
处理SwiftData数据库
选择File – Open database…
找到前面提到的default.store文件,并双击打开该数据库文件。
在DB Browser for SQLite文件中顶部找到“Browse Data”。
下面是典型的CoreData或SwiftData数据库结构。
ACHNAGE: 这个表通常用于存储有关数据变化的元数据,如变更跟踪或版本控制信息。具体用途取决于你的应用逻辑。
ATRANSACTION: 此表用于记录事务信息。事务是数据库操作的基本单位,通常用于确保一组操作要么全部成功,要么全部失败,以维护数据的一致性。
ATRANSACTIONSTRING: 这个表可能包含与事务相关的字符串信息,通常用于存储与特定事务有关的描述或元数据。
ZPERSON: 这个表通常与 Person 类相关,存储 Person 实例的数据。字段可能包括 name、age 和 id 等属性。
Z_METADATA: 此表存储有关数据库模式和结构的元数据,包括表的结构、索引和其他属性的信息。
Z_MODELCACHE: 用于缓存模型对象,以提高性能。这个表可能存储最近使用的对象的状态,避免频繁从磁盘加载。
Z_PRIMARYKEY: 此表通常用于存储各个表的主键值,以确保唯一性。它可能用于管理对象标识符,确保在数据存储中不会有重复的主键。
我在Swift中设置的是Person类。
因此,查找的是ZPERSON这个表。
可以通过右侧区域修改对应字段的数据。
因此,我这里的问题是存在多个重复数据,所以可以在上方找到“Execute SQL(执行SQL)”标签,在底部输入查找或删除数据的代码:
SELECT * FROM ZPERSON
查询到多个文件(这里是删除前的数据截图),然后通过输入对应的删除代码:
BEGIN TRANSACTION;
DELETE FROM ZPERSON WHERE rowid NOT IN (
SELECT MIN(rowid) FROM ZPERSON GROUP BY Zid
) AND Zid IN (
SELECT Zid FROM ZPERSON GROUP BY Zid HAVING COUNT(*) > 1
);
COMMIT;
删除后,就剩下最后一条数据。
除此之外,如果没有在代码中没有显式提交事务:
BEGIN TRANSACTION;
DELETE FROM ZPERSON WHERE ...; -- 你的删除条件
COMMIT;
修改的数据库内容就不会保存成功,因此可以点击Write Changes按钮保存数据。
最后,对应的设备数据内容也会同步更新。
数据修改完成,以上就是全部的SwiftData数据的修改内容。