iOS RealmSwift赢得';t将默认数据库路径更改为组路径后更新模型

iOS RealmSwift赢得';t将默认数据库路径更改为组路径后更新模型,ios,swift,xcode,realm,share-extension,Ios,Swift,Xcode,Realm,Share Extension,我在我的应用程序中使用realm已经有一段时间了。现在我已经向应用程序添加了共享扩展名,我注意到我需要定义组子目录的默认文件路径,这样我就可以从应用程序和扩展名访问同一个数据库。我搜索了好几次,在和的帮助下找到了最佳解决方案 这是我的AppDelegate文件 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptions

我在我的应用程序中使用realm已经有一段时间了。现在我已经向应用程序添加了共享扩展名,我注意到我需要定义组子目录的默认文件路径,这样我就可以从应用程序和扩展名访问同一个数据库。我搜索了好几次,在和的帮助下找到了最佳解决方案

这是我的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()
方法中的一个,这些方法都不能正常工作,取消注释第一个后,我可以登录(创建用户实例),重新启动应用程序后,它可以正确读取用户数据,但是消息根本不会出现在应用程序中,这意味着读/写消息时有问题,当取消注释
configRealm
时,它应该只更改领域路径,不迁移旧数据,应用程序仍然会显示旧消息,但不会加载用户,这意味着重新启动后我的登录状态消失,此外,如果我更新了一个消息属性,使领域更改为消息模型属性,则会抛出此错误,应用程序会崩溃:

*由于未捕获的异常“RLMEException”而终止应用程序,原因: '试图在写入事务外部修改对象-调用 首先在RLMRealm实例上开始WriteTransaction。“ *第一次抛出调用堆栈

这个错误表示我在领域写闭包之外执行更新操作,但是我的代码在更改路径之前工作得很好,而且我确实在写块内部编写了更新命令,正如您在这里看到的,这是我的消息更新方法

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
    }
}
我不知道我是否犯了错误,或者这是一个领域问题或XCode问题(我使用测试版) 此刻我非常困惑

我使用领域3.7.5
XCode 10 Beta版

我通过将自定义配置设置为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)
}

我不知道你的错误,但你可以看看它到底在哪里,为什么thrown@TmKVU实际上我这样做了,任何领域写闭包中的第一个赋值行都会抛出错误,例如在我放在这里的更新函数中,第一行是self.content=content??自我控制