有时候背景领域会丢失所有数据库

时间:2016-12-12 17:45:30

标签: ios swift realm

我正在使用Realm 2.1.1,并且自版本0.98以来一直在使用。

当用户进入后台时,有时会发生1小时或更长时间后,Realm数据库会丢失其所有对象。

已经检查过,我不会在后台进行任何保存或检索某些对象。

我在didFinishLaunchingWithOptions上执行了对应用程序组的迁移,因为我使用的是Widget,我认为这导致了问题,因为它试图从另一个线程访问域。 领域数据库是加密的,所以我不知道它是否可以从钥匙串进入后台。

继承我的代码以初始化RealmDatabase:

class func migrateRealm() {
    let config = RLMRealmConfiguration.defaultConfiguration()
    config.schemaVersion = realmSchemeVersion()
    config.migrationBlock = {(migration:RLMMigration, oldSchemaVersion: UInt64) in }
    RLMRealmConfiguration.setDefaultConfiguration(config)

    //Cache original realm path (documents directory)

    guard let originalDefaultRealmPath = RealmEncrypted.realm().configuration.fileURL?.absoluteString else {
        return
    }

    //Generate new realm path based on app group
    let appGroupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("app")!
    let realmPath = appGroupURL.URLByAppendingPathComponent("default.realm")?.path ?? ""
    //Moves the realm to the new location if it hasn't been done previously

    if (NSFileManager.defaultManager().fileExistsAtPath(originalDefaultRealmPath) && !NSFileManager.defaultManager().fileExistsAtPath(realmPath)) {
        do {
            try NSFileManager.defaultManager().moveItemAtPath(originalDefaultRealmPath, toPath: realmPath)
            //Set the realm path to the new directory
            config.fileURL = NSURL(string: realmPath)
            RLMRealmConfiguration.setDefaultConfiguration(config)

            do {
                try NSFileManager.defaultManager().removeItemAtURL(NSURL(string: originalDefaultRealmPath)!)
            }
            catch let error as NSError {
                print("Ooops! Something went wrong deleting : \(error)")
            }
        }
        catch let error as NSError {
            print("Ooops! Something went wrong: \(error)")
        }
    }
    else {
        config.fileURL = NSURL(string: realmPath)
        RLMRealmConfiguration.setDefaultConfiguration(config)
    }
}

1 个答案:

答案 0 :(得分:0)

在代码级别上,我可以看到的唯一可能导致问题的是您在内存中创建Realm实例,然后尝试移动它。

执行此操作的特定行是guard let originalDefaultRealmPath = RealmEncrypted.realm().configuration.fileURL

Realm在内部缓存Realm的副本,以便在后续调用中回收它们。因此,如果在内存中创建引用,然后在磁盘上移动物理文件,则会导致意外行为,甚至可能导致数据丢失。

最佳做法是尝试直接使用负责创建此Realm的Configuration对象。如果您绝对需要访问Realm然后想要在磁盘上移动文件,则可以将该代码封装在@autoreleasepool中,以保证在移动文件之前从内存中删除Realm实例。 / p>

就您可能需要考虑的其他潜在事项而言:您可能需要change your file access permissions才能在后台写入Realm文件。

此外,您可能是正确的,因为您在应用程序背景化时也无法访问钥匙串值。显然another SO question that talks about this