境界迁移记录不充分。任何人都可以澄清吗?

时间:2017-07-07 05:30:20

标签: ios realm

在Realm数据库上执行迁移的文档很少,文档似乎已过时。有两个方面解释了如何迁移数据:

- Realm网站上的简单示例:https://realm.io/docs/swift/latest/

- Github示例部分中的更详细示例:https://github.com/realm/realm-cocoa/blob/master/examples/ios/swift-3.0/Migration/AppDelegate.swift

这些示例都没有充分说明如何在架构版本之间迁移数据。我尝试过玩这些示例,但还没有让任何迁移工作。同样,我在升级到没有架构更改和数据更改的较新Realm版本时遇到应用程序崩溃问题,这些问题在模拟器中不会发生,但在从TestFlight或App Store安装应用程序时会发生。 / p>

似乎Realm文档和详细说明迁移的示例应该进行刷新。我感兴趣的领域是:

  1. 在数据库中未升级架构的情况下升级到较新的Realm版本。不清楚是否应继续使用以前版本生成的default.realm文件,或者是否需要使用较新的Realm框架版本重新生成default.realm文件。

  2. 向Realm对象添加新属性。

  3. 新对象("行")添加到现有类而没有任何架构更改。

  4. 数据库中的现有类没有架构更改,但添加了一个或多个全新的类。

  5. 上述任意组合。

  6. 谢谢!

2 个答案:

答案 0 :(得分:4)

抱歉文档不够用。我们感谢您的反馈意见,并将用它来改进它们。与此同时,让我回答你的问题:

  1. 升级SDK时无需执行任何操作。有时,我们会升级核心数据库文件格式,但是当您打开领域(Realm())时会自动进行此迁移,因此您不必担心它。
  2. 向对象添加新属性时,只需按照此代码段进行操作即可。
  3. 迁移块中不需要任何内容​​,因为此块只是在版本之间应用数据转换。您需要做的就是增加schemaVersion

    // Inside your application(application:didFinishLaunchingWithOptions:)
    
    let config = Realm.Configuration(
      // Set the new schema version. This must be greater than the previously used
      // version (if you've never set a schema version before, the version is 0).
      schemaVersion: 1,
    
      // Set the block which will be called automatically when opening a Realm with
      // a schema version lower than the one set above
      migrationBlock: { migration, oldSchemaVersion in
        // We haven’t migrated anything yet, so oldSchemaVersion == 0
        if (oldSchemaVersion < 1) {
          // Nothing to do!
          // Realm will automatically detect new properties and removed properties
          // And will update the schema on disk automatically
        }
      })
    
    // Tell Realm to use this new configuration object for the default Realm
    Realm.Configuration.defaultConfiguration = config
    
    // Now that we've told Realm how to handle the schema change, opening the file
    // will automatically perform the migration
    let realm = try! Realm()
    
    1. 向Realm添加对象不会影响架构,因此迁移不相关。
    2. 这与2相同,您只需要增加schemaVersion,但您不必在迁移块中执行任何操作,因为Realm会处理所有内容。迁移块用于自定义迁移逻辑,例如,您希望在更新为firstName时将lastNameschemaVersion=0fullName转换为schemaVersion=1。在这种情况下,您可以从旧版本获取数据,并将字符串连接到迁移块中的新fullName属性。
    3. 希望这有帮助!

答案 1 :(得分:0)

不幸的是,这根本行不通。几个月前我必须添加一段代码才能让Realm工作,但它并没有解决我遇到的迁移问题:

      config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent("default-v1.realm")
  Realm.Configuration.defaultConfiguration = config

  // copy over old data files for migration
  //let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
  let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
  //print("Realm.Configuration.defaultConfiguration.fileURL! = \(defaultURL)")
  //let defaultParentURL = defaultURL.URLByDeletingLastPathComponent

  if let realmURL = bundleURL("default-v1") {
    do {
      //print("Bundle location for default.realm = \(realmURL)")
      let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
      let url = URL(fileURLWithPath: path)
      let filePath = url.appendingPathComponent("default-v1.realm").path
      let fileManager = FileManager.default
      if fileManager.fileExists(atPath: filePath) {

         print("FILE INSTALLED")
        print("Documents location for default.realm = \(filePath)")
      } else {
        //print("FILE NOT INSTALLED, COPYING default.realm from bundle to Documents directory.")
        try FileManager.default.copyItem(at: realmURL, to: defaultURL)
      }
    } catch {}
  }

我怀疑新的default-v1.realm文件可能会破坏用户设备上的现有default-v1.realm文件,使用此代码并使用“Nothing is needed”迁移方法。

部分混淆源于https://github.com/realm/realm-cocoa/tree/master/examples/ios/swift-3.0/Migration处的示例迁移代码,其中来自v1文件的数据被复制到v2文件。无论如何,我已经尝试了你发布的“Nothing is needed”代码,但应用程序找不到任何Realm数据然后崩溃。

看起来我可以将您发布的代码拼接到我一直使用的代码中,然后也许可以解决问题。将在下周调查。

感谢您的回复!