迅速地,有一种方法可以从第二个Realm捆绑包中添加新数据,而不会覆盖当前Default Realm中的任何现有数据? [英] In swift, is there a way to add new data from second Realm bundle, without overwriting any existing data in the current Default Realm?

查看:52
本文介绍了迅速地,有一种方法可以从第二个Realm捆绑包中添加新数据,而不会覆盖当前Default Realm中的任何现有数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在应用程序的初始加载时,捆绑的领域(Realm1)被复制到documents文件夹.现在,将绑定的领域设置为默认领域,我可以更新bool属性,以便表视图可以显示已标记和未标记的单元格.但是,我正在寻找一种将第二个领域(Realm2)与以后的更新捆绑在一起的方法,该更新会将新数据添加到现有的默认领域,但又不覆盖当前的默认领域.如果有帮助,我目前正在使用Swift 5和Xcode 11.1.

Upon initial load of the app, the Bundled Realm (Realm1) is copied to the documents folder. Now that the bundled realm is set as the default realm, I am able update the bool property so that the table view can show marked and unmarked cells. However I am looking for a way to bundle a second realm (Realm2) with a later update, that will add new data to the existing default realm, but without overwriting the current default realm. I am currently working in swift 5 and Xcode 11.1, if that is helpful.

到目前为止,我唯一能想到的就是添加代码块以将新条目添加到默认领域.首先,该视图将检查以查看该领域的计数,如果该计数与原始捆绑相同,则它将添加新数据;如果该计数等于初始捆绑加上新条目,则它将添加新数据.不会再次添加新数据.我一直希望有一个更简单的解决方案,我认为它更干净.

So far the only thing that I can think of is adding block of code to add new entries to the default realm. First the view will check to see what the count is of the realm, and if the count is the same as the original bundle, then it will add new data, if the count is equal to the initial bundle plus the new entries, then it will not add the new data again. I was hoping for a simpler solution that is cleaner in my opinion.

理想情况下,最终结果将是一种更新现有默认领域的方法,而不会覆盖已编辑的内容.尽管我对使用领域还不是很陌生,但是如果能为我指出正确的解决方案,将大有帮助.谢谢.

Ideally the end result would be a way to update the existing default realm, without overwriting the already edited content. Although I am rather new to using realm, any help in pointing me in the right direction for a solution would be greatly appreciated. Thanks.

下面附上了我为从包中加载默认领域而实现的当前代码.

Attached below is the current code I have implemented to load the default realm from the bundle.



    let bundlePath = Bundle.main.path(forResource: "preloadedData", ofType: "realm")!
            let defaultPath = Realm.Configuration.defaultConfiguration.fileURL!.path
            let fileManager = FileManager.default

    //        Copy Realm on initial launch
            if !fileManager.fileExists(atPath: defaultPath){
                do {
                    try fileManager.copyItem(atPath: bundlePath, toPath: defaultPath)
                    print("Realm was copied")
                } catch {
                    print("Realm was not coppied \(error)")
                }
            }
            return true

推荐答案

我要添加一个与第一个答案有些相关但也可以独立存在的答案.

I am adding an additional answer that's somewhat related to the first but also stands on it's own.

简而言之,一旦Realm连接到数据源,只要没有释放对象,Realm就会继续使用该数据源,即使实际文件被删除.

In a nutshell, once Realm connects to a data source, it will continue to use that data source as long as the objects are not released, even if the actual file is deleted.

解决方法是将Realm调用封装到一个自动释放池中,以便在删除Realm时可以释放这些对象.

The way around that is to encapsulate the Realm calls into an autorelease pool so that those objects can be released when the Realm is deleted.

这是一个例子:

此函数将GameData对象添加到default.realm文件.

This function adds a GameData object to the default.realm file.

func addAnObject() {
   autoreleasepool {
      let realm = try! Realm()
      let testData = GameData()
      testData.Scenario = "This is my scenario"
      testData.Id = 1
      try! realm.write {
         realm.add(testData)
      }
   }
}

这时,如果您运行addAnObject代码,则文件将具有GameData对象.

At this point, if you run the addAnObject code, your file will have a GameData object.

GameData {
    Id = 1;
    GameDate = (null);
    Scenario = This is my scenario;
    GameStarted = 0;
}

然后是一个功能,该功能删除旧的领域,然后将捆绑的领域复制到它的位置.之所以可行,是因为与Realm的所有交互都包含在自动释放池中,因此可以释放对象.

Then a function that delete’s the old realm, and copies the bundled realm to it’s place. This works because all of the interaction with Realm was enclosed in an autorelease pool so the objects can be released.

func createDefaultRealm() {
   let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
   let defaultParentURL = defaultURL.deletingLastPathComponent()

   if let bundledRealmURL = self.bundleURL("default") {
      do {
         try FileManager.default.removeItem(at: defaultURL)
         try FileManager.default.copyItem(at: bundledRealmURL, to: defaultURL)
      } catch let error as NSError {
          print(error.localizedDescription)
          return
      }
   }

   let migrationBlock : MigrationBlock = { migration, oldSchemaVersion in
      //handle migration
   }

   Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 18, migrationBlock: migrationBlock)

   print("Your default realm objects: \(try! Realm().objects(GameData.self))")
}

func bundleURL(_ name: String) -> URL? {
    return Bundle.main.url(forResource: name, withExtension: "realm")
}

,请注意,如果您在类内访问Realm但在自动释放池之外,Realm将拒绝放开"它的对象.

and please note that if you access Realm inside the class but outside an autorelease pool, Realm will refuse to 'let go' of it's objects.

请勿这样做!

class ViewController: UIViewController {
    var realm = try! Realm()

这篇关于迅速地,有一种方法可以从第二个Realm捆绑包中添加新数据,而不会覆盖当前Default Realm中的任何现有数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆