iOS 将默认数据库路径更改为组路径后,RealmSwift 不会更新模型
iOS RealmSwift won't update models after changing default database path to group path
我在我的应用程序中使用领域已有一段时间了。现在我已经向应用程序添加了共享扩展,我注意到我需要定义组子目录的领域默认文件路径,这样我就可以从应用程序和扩展访问同一个数据库。我搜索了几次,在 and with the help of here.
中找到了最佳解决方案
这是我的 AppDelegate 文件
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// migrateRealm()
// configRealm()
return true
}
private func configRealm() {
let fileURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hjri.khandehland")!
.appendingPathComponent("Library/Caches/default.realm")
let config = Realm.Configuration(fileURL: fileURL)
Realm.Configuration.defaultConfiguration = config
}
private func migrateRealm() {
let fileManager = FileManager.default
let originalDefaultRealmURL = Realm.Configuration.defaultConfiguration.fileURL
//Cache original realm path (documents directory)
let originalDefaultRealmPath = originalDefaultRealmURL?.path
//Generate new realm path based on app group
let realmURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hjri.khandehland")!
.appendingPathComponent("Library/Caches/default.realm")
let realmPath = realmURL.path
if originalDefaultRealmPath != nil {
//Moves the realm to the new location if it hasn't been done previously
if (fileManager.fileExists(atPath: originalDefaultRealmPath!) && !fileManager.fileExists(atPath: realmPath)) {
print("***** FILE EXISTS AND MOVING")
do {
try fileManager.moveItem(atPath: originalDefaultRealmPath!, toPath: realmPath)
} catch {
print("***** REALM FILE PATH MIGRATION ERROR *****")
}
} else {
print ("***** FILE DOES NOT EXIST *****")
}
}
//Set the realm path to the new directory
Realm.Configuration.defaultConfiguration.fileURL = realmURL
}
另外,我的模型类是
class User: Object {
@objc dynamic var username: String = ""
@objc dynamic var email: String = ""
@objc dynamic var password: String = ""
@objc dynamic var accessToken: String = ""
@objc dynamic var refreshToken: String = ""
}
class Message: Object {
@objc dynamic var id: Int = 0
@objc dynamic var content: String = ""
@objc dynamic var submitDate: String = ""
@objc dynamic var submitDateEpoch: Double = 0
@objc dynamic var favoriteCount:Int = 0
@objc dynamic var isFavorite: Bool = false
@objc dynamic var needsSync: Bool = false
@objc dynamic var syncDetails: String = ""
@objc dynamic var isNew: Bool = true
}
为了测试我的应用程序,我首先使用默认领域文件路径处理模型,然后我取消注释 migrateRealm()
或 configRealm()
方法之一,其中 none 不会正常工作,取消注释第一个后,我可以登录(创建用户实例)并在重新启动应用程序后,它正确读取用户数据,但消息根本不会出现在应用程序中,这意味着 reading/writing 他们,当取消注释 configRealm
应该只更改领域路径而不迁移旧数据时,应用程序仍然向我显示旧消息,但它不会加载用户,这意味着我的重新启动后登录状态消失,而且如果我更新一条消息 属性 使领域更改消息模型 属性,它会抛出此错误并且应用程序崩溃:
* Terminating app due to uncaught exception 'RLMException', reason:
'Attempting to modify object outside of a write transaction - call
beginWriteTransaction on an RLMRealm instance first.'
* First throw call stack
这个错误表明我正在领域写闭包之外进行更新操作,但我的代码在更改路径之前运行良好,而且我确实在写块内编写了更新命令,如您在此处所见, 这是我的消息更新方法
func update(content: String? = nil, isFavorite: Bool? = nil, needsSync: Bool? = nil, syncDetails: String? = nil, favoriteCount: Int? = nil) {
let realm = try! Realm()
try! realm.write {
self.content = content ?? self.content
self.isFavorite = isFavorite ?? self.isFavorite
self.needsSync = needsSync ?? self.needsSync
self.syncDetails = syncDetails ?? self.syncDetails
self.favoriteCount = favoriteCount ?? self.favoriteCount
}
}
不知道是我写错了还是realm问题还是XCode问题(我用的是内测版)
此刻很迷茫
我用的是Realm 3.7.5
XCode 10 个测试版
我通过在每次调用它时将我的自定义配置设置为 Realm 实例来使其工作,我通过计算 属性 并在我想使用 Realm
的任何时候调用它使它变得更容易
static var realmInstance: Realm {
let fileURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier)!.appendingPathComponent(databaseFileName)
var config = Realm.Configuration(fileURL: fileURL)
return try! Realm(configuration: config)
}
我在我的应用程序中使用领域已有一段时间了。现在我已经向应用程序添加了共享扩展,我注意到我需要定义组子目录的领域默认文件路径,这样我就可以从应用程序和扩展访问同一个数据库。我搜索了几次,在
这是我的 AppDelegate 文件
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// migrateRealm()
// configRealm()
return true
}
private func configRealm() {
let fileURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hjri.khandehland")!
.appendingPathComponent("Library/Caches/default.realm")
let config = Realm.Configuration(fileURL: fileURL)
Realm.Configuration.defaultConfiguration = config
}
private func migrateRealm() {
let fileManager = FileManager.default
let originalDefaultRealmURL = Realm.Configuration.defaultConfiguration.fileURL
//Cache original realm path (documents directory)
let originalDefaultRealmPath = originalDefaultRealmURL?.path
//Generate new realm path based on app group
let realmURL = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hjri.khandehland")!
.appendingPathComponent("Library/Caches/default.realm")
let realmPath = realmURL.path
if originalDefaultRealmPath != nil {
//Moves the realm to the new location if it hasn't been done previously
if (fileManager.fileExists(atPath: originalDefaultRealmPath!) && !fileManager.fileExists(atPath: realmPath)) {
print("***** FILE EXISTS AND MOVING")
do {
try fileManager.moveItem(atPath: originalDefaultRealmPath!, toPath: realmPath)
} catch {
print("***** REALM FILE PATH MIGRATION ERROR *****")
}
} else {
print ("***** FILE DOES NOT EXIST *****")
}
}
//Set the realm path to the new directory
Realm.Configuration.defaultConfiguration.fileURL = realmURL
}
另外,我的模型类是
class User: Object {
@objc dynamic var username: String = ""
@objc dynamic var email: String = ""
@objc dynamic var password: String = ""
@objc dynamic var accessToken: String = ""
@objc dynamic var refreshToken: String = ""
}
class Message: Object {
@objc dynamic var id: Int = 0
@objc dynamic var content: String = ""
@objc dynamic var submitDate: String = ""
@objc dynamic var submitDateEpoch: Double = 0
@objc dynamic var favoriteCount:Int = 0
@objc dynamic var isFavorite: Bool = false
@objc dynamic var needsSync: Bool = false
@objc dynamic var syncDetails: String = ""
@objc dynamic var isNew: Bool = true
}
为了测试我的应用程序,我首先使用默认领域文件路径处理模型,然后我取消注释 migrateRealm()
或 configRealm()
方法之一,其中 none 不会正常工作,取消注释第一个后,我可以登录(创建用户实例)并在重新启动应用程序后,它正确读取用户数据,但消息根本不会出现在应用程序中,这意味着 reading/writing 他们,当取消注释 configRealm
应该只更改领域路径而不迁移旧数据时,应用程序仍然向我显示旧消息,但它不会加载用户,这意味着我的重新启动后登录状态消失,而且如果我更新一条消息 属性 使领域更改消息模型 属性,它会抛出此错误并且应用程序崩溃:
* Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.' * First throw call stack
这个错误表明我正在领域写闭包之外进行更新操作,但我的代码在更改路径之前运行良好,而且我确实在写块内编写了更新命令,如您在此处所见, 这是我的消息更新方法
func update(content: String? = nil, isFavorite: Bool? = nil, needsSync: Bool? = nil, syncDetails: String? = nil, favoriteCount: Int? = nil) {
let realm = try! Realm()
try! realm.write {
self.content = content ?? self.content
self.isFavorite = isFavorite ?? self.isFavorite
self.needsSync = needsSync ?? self.needsSync
self.syncDetails = syncDetails ?? self.syncDetails
self.favoriteCount = favoriteCount ?? self.favoriteCount
}
}
不知道是我写错了还是realm问题还是XCode问题(我用的是内测版) 此刻很迷茫
我用的是Realm 3.7.5 XCode 10 个测试版
我通过在每次调用它时将我的自定义配置设置为 Realm 实例来使其工作,我通过计算 属性 并在我想使用 Realm
的任何时候调用它使它变得更容易static var realmInstance: Realm {
let fileURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier)!.appendingPathComponent(databaseFileName)
var config = Realm.Configuration(fileURL: fileURL)
return try! Realm(configuration: config)
}