首先我在 SwiftUI 之外使用共享实例
let realm:Realm!
let container = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ProjectSettings.group)!
static let shared = RealmDatabaseManager()
init(){
let defaultURL = Realm.Configuration.defaultConfiguration.fileURL
let realmURL = container.appendingPathComponent("default.realm")
//check if there's file in realmurl
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: realmURL.path) {
try? fileManager.copyItem(at: defaultURL!, to: realmURL)
}
// Config init
let config = Realm.Configuration(fileURL: realmURL, schemaVersion: 9,migrationBlock: {migration,oldVersion in
if oldVersion < 3 {
migration.enumerateObjects(ofType: WordRecordRealm.className()) { oldObject, newObject in
//some works here
}
})
Realm.Configuration.defaultConfiguration = config
realm = try! Realm(configuration: config)
}
}
没有错误,但当我更改 schemaVersion 时,迁移块永远不会被调用。
然后我看到了一种将领域配置写入 swiftui 环境的方法,并在 SwiftUI 中使用 @ObservedResuts 和 @ObservedRealmObject
var body: some Scene {
WindowGroup {
RouterView()
.environment(\.realmConfiguration, Realm.Configuration(fileURL: realmURL, schemaVersion: 32,migrationBlock: {migration,oldVersion in
//some works here
))
正常调用。但是,我想在 SwiftUI View 之外保存 Realm 的全局实例,因此我仍然需要使用第一段代码。但是只要我写的和环境中的配置一样,环境中的迁移部分就不会再被调用了
最奇怪的是,在应该调用迁移块的时间点,这个共享实例仍然没有初始化。如果我删除共享实例中的架构版本,则会再次调用迁移,但此共享实例不起作用,导致版本不匹配。
事实证明,我的小部件总是在加载主应用程序环境之前初始化共享对象。然后我创建一个
class RealmConfiguration{
static let realmURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: ProjectSettings.group)!.appendingPathComponent("default.realm")
static func getConfig()->Realm.Configuration{
let config = Realm.Configuration(fileURL: RealmConfiguration.realmURL,schemaVersion: 40) { migration, oldVersion in
if oldVersion < 3 {
migration.enumerateObjects(ofType: WordRecordRealm.className()) { oldObject, newObject in
}
return config
}
}
我在主应用程序的环境中调用此函数,而不是使用共享领域对象初始化小部件,而是使用 @ObservedResults 并在时间线提供程序的 init 函数中将领域默认配置设置为此配置。现在一切似乎都正常。