如何备份并恢复iOS应用的SwiftData数据库(支持Mac文件区访问)
备份iOS应用SwiftData数据库并让Mac可访问的方法
要实现备份SwiftData数据库且让Mac连接iPhone时能在文件区域找到备份文件,核心是把数据库文件迁移到应用的可共享目录,下面是具体步骤:
一、先明确SwiftData默认存储位置
SwiftData默认把数据库文件存在应用的Library/Application Support/[你的应用Bundle ID]目录下,核心文件是default.store,还有.wal、.shm两个事务日志文件——这三个必须一起备份,否则数据库可能损坏无法正常使用。
二、让备份文件能被Mac识别访问
要让Mac在「访达」的iPhone文件区域看到备份,需先开启应用的文件共享权限,再把数据库文件复制到Documents目录下。
1. 开启文件共享权限
在Xcode中打开项目的Info.plist,添加以下配置:
<key>UIFileSharingEnabled</key> <true/> <key>LSSupportsOpeningDocumentsInPlace</key> <true/>
添加后,你的应用会出现在Mac访达的iPhone「文件」列表里,可直接访问Documents目录。
2. 编写备份逻辑
把SwiftData的数据库文件复制到Documents下的专属备份文件夹,示例代码如下:
import SwiftData import Foundation func backupSwiftDataDB() { // 获取当前SwiftData容器的存储路径 let container = try! ModelContainer(for: YourModel.self) guard let storeURL = container.configurations.first?.url else { print("无法获取SwiftData存储路径") return } // 定义备份目录:Documents下的SwiftDataBackup文件夹 let backupDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] .appending(path: "SwiftDataBackup") // 若备份目录不存在则创建 try? FileManager.default.createDirectory(at: backupDir, withIntermediateDirectories: true) // 复制核心数据库文件 let backupStoreURL = backupDir.appending(path: storeURL.lastPathComponent) try? FileManager.default.copyItem(at: storeURL, to: backupStoreURL) // 复制事务日志文件(如果存在) let walURL = storeURL.deletingPathExtension().appendingPathExtension("wal") let shmURL = storeURL.deletingPathExtension().appendingPathExtension("shm") if FileManager.default.fileExists(atPath: walURL.path()) { try? FileManager.default.copyItem(at: walURL, to: backupDir.appending(path: walURL.lastPathComponent)) } if FileManager.default.fileExists(atPath: shmURL.path()) { try? FileManager.default.copyItem(at: shmURL, to: backupDir.appending(path: shmURL.lastPathComponent)) } print("备份完成,文件路径:\(backupDir.path())") }
注意:将YourModel.self替换成你实际的SwiftData模型类。
3. 触发备份操作
你可以在应用内添加一个按钮,点击时调用backupSwiftDataDB()方法,也可以设置在应用进入后台时自动执行备份。
三、从备份恢复数据库
恢复时需要先关闭当前的ModelContainer,再将备份文件复制回原存储目录,最后重新初始化容器。示例代码:
func restoreSwiftDataDB() { // 先关闭现有容器(假设你持有容器引用:var modelContainer: ModelContainer?) modelContainer = nil // 定位备份文件路径 let backupDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] .appending(path: "SwiftDataBackup") let backupStoreURL = backupDir.appending(path: "default.store") guard FileManager.default.fileExists(atPath: backupStoreURL.path()) else { print未找到备份文件") return } // 获取SwiftData默认存储路径 let targetContainer = try! ModelContainer(for: YourModel.self) guard let targetStoreURL = targetContainer.configurations.first?.url else { print("无法获取目标存储路径") return } // 替换核心数据库文件 try? FileManager.default.removeItem(at: targetStoreURL) try? FileManager.default.copyItem(at: backupStoreURL, to: targetStoreURL) // 替换事务日志文件 let backupWalURL = backupDir.appending(path: "default.wal") let targetWalURL = targetStoreURL.deletingPathExtension().appendingPathExtension("wal") if FileManager.default.fileExists(atPath: backupWalURL.path()) { try? FileManager.default.removeItem(at: targetWalURL) try? FileManager.default.copyItem(at: backupWalURL, to: targetWalURL) } let backupShmURL = backupDir.appending(path: "default.shm") let targetShmURL = targetStoreURL.deletingPathExtension().appendingPathExtension("shm") if FileManager.default.fileExists(atPath: backupShmURL.path()) { try? FileManager.default.removeItem(at: targetShmURL) try? FileManager.default.copyItem(at: backupShmURL, to: targetShmURL) } // 重新初始化容器 modelContainer = try? ModelContainer(for: YourModel.self) print("恢复完成") }
四、Mac上访问备份文件的步骤
iPhone连接Mac后:
- 打开「访达」,在左侧边栏找到你的iPhone设备
- 切换到「文件」标签页,找到你的应用名称
- 打开「SwiftDataBackup」文件夹,即可看到备份的数据库文件
内容的提问来源于stack exchange,提问作者InsideLoop
相关产品推荐
相关产品推荐

