ios RLMException,对象类型需要迁移

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33363508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:06:27  来源:igfitidea点击:

RLMException, Migration is required for object type

iosswiftrealm

提问by shahin ali agharia

I have an object NotSureItemin which I have three properties titlewhose name is renamed from textand textDescriptionwhich I had added later and a dateTimeproperty. Now when I am going to run my app it crashes when I want to add something to these properties. It shows following statements.

我有一个对象NotSureItem中,我有三个属性title的名字是从更名texttextDescription我已经后来添加和dateTime财产。现在,当我要运行我的应用程序时,当我想向这些属性添加某些内容时它会崩溃。它显示了以下语句。

'Migration is required for object type 'NotSureItem' due to the following errors:
- Property 'text' is missing from latest object model.
- Property 'title' has been added to latest object model.
- Property 'textDescription' has been added to latest object model.'

Here is my code:

这是我的代码:

import Foundation
import Realm

class NotSureItem: RLMObject {
    dynamic var title = ""   // renamed from 'text'
    dynamic var textDescription = "" // added afterwards
    dynamic var dateTime = NSDate()
}

回答by joern

As long as you have not released your appyou can simply delete your app and run it again.

只要您还没有发布您的应用程序,您就可以简单地删除您的应用程序并再次运行它。

Everytime you change properties on your Realm objects your existing database becomes incompatible to the new one.

每次更改 Realm 对象的属性时,现有数据库都会与新数据库不兼容。

As long as you are still in the developing stage you can simply delete the app from the simulator / device and start it again.

只要您仍处于开发阶段,您就可以简单地从模拟器/设备中删除应用程序并重新启动它。

Later when your app has been releasedand you change properties on your objects you have to implement a migration to the new database version.

稍后当您的应用程序发布并且您更改对象的属性时,您必须迁移到新的数据库版本。

To actually perform a migration you implement a Realm migration block. Typically you would add the block to application(application:didFinishLaunchingWithOptions:):

要实际执行迁移,您需要实现 Realm 迁移块。通常,您会将块添加到application(application:didFinishLaunchingWithOptions:)

var configuration = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        if oldSchemaVersion < 1 {

            // if just the name of your model's property changed you can do this 
            migration.renameProperty(onType: NotSureItem.className(), from: "text", to: "title")

            // if you want to fill a new property with some values you have to enumerate
            // the existing objects and set the new value
            migration.enumerateObjects(ofType: NotSureItem.className()) { oldObject, newObject in
                let text = oldObject!["text"] as! String
                newObject!["textDescription"] = "The title is \(text)"
            }

            // if you added a new property or removed a property you don't
            // have to do anything because Realm automatically detects that
        }
    }
)
Realm.Configuration.defaultConfiguration = configuration

// opening the Realm file now makes sure that the migration is performed
let realm = try! Realm()

Whenever your scheme changes your have to increase the schemaVersionin the migration block and update the needed migration within the block.

每当您的方案更改时,您都必须增加schemaVersion迁移块中的 并更新块内所需的迁移。

回答by CodeBrew

Delete the app and re-install is not a good practice. We should incorporate some migration steps during development from the first time we encounter migration need. The link given by SilentDirge is good: realm migration document, which gives good examples for handling different situations.

删除应用程序并重新安装不是一个好习惯。从我们第一次遇到迁移需求开始,我们就应该在开发过程中加入一些迁移步骤。SilentDirge 给出的链接很好:realm migration document,它提供了处理不同情况的好例子。

For a minimum migration task, the following code snippet from the above link can automatically do the migration and is to be used with AppDelegate's disFinishLaunchWithOptionsmethod:

对于最小迁移任务,上面链接中的以下代码片段可以自动执行迁移,并与 AppDelegate 的disFinishLaunchWithOptions方法一起使用:

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 _ = try! Realm()

回答by Vignesh

Below code is working for me

下面的代码对我有用

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{  
RLMRealmConfiguration *config = [RLMRealmConfiguration    defaultConfiguration];
 config.schemaVersion = 2;
config.migrationBlock = ^(RLMMigration *migration, uint64_t  oldSchemaVersion) {
  // The enumerateObjects:block: method iterates
  // over every 'Person' object stored in the Realm file
  [migration enumerateObjects:Person.className
                    block:^(RLMObject *oldObject, RLMObject *newObject) {
    // Add the 'fullName' property only to Realms with a schema version of 0
    if (oldSchemaVersion < 1) {
      newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
                            oldObject[@"firstName"],
                            oldObject[@"lastName"]];
    }

    // Add the 'email' property to Realms with a schema version of 0 or 1
    if (oldSchemaVersion < 2) {
     newObject[@"email"] = @"";
    }
  }];
 };
[RLMRealmConfiguration setDefaultConfiguration:config];

// now that we have updated the schema version and provided a migration block,
// opening an outdated Realm will automatically perform the migration and
// opening the Realm will succeed
[RLMRealm defaultRealm];

return YES;
}

More info : https://realm.io/docs/objc/latest/#getting-started

更多信息:https: //realm.io/docs/objc/latest/#getting-started

回答by SilentDirge

Your modified database is no longer compatible with the saved database which is why a migration is required. Your options are to delete the old database file and start fresh (works great if you are in the initial dev phase), or if you are live, do the migration.

您修改后的数据库不再与保存的数据库兼容,这就是需要迁移的原因。您的选择是删除旧的数据库文件并重新开始(如果您处于初始开发阶段,效果很好),或者如果您处于活动状态,则进行迁移。

You do this by defining a schema version and providing a database migration 'script' within your Realm configuration. The entire process is documented here (along with code samples): here

您可以通过定义架构版本并在 Realm 配置中提供数据库迁移“脚本”来完成此操作。整个过程记录在此处(以及代码示例):此处

回答by protspace

You can erase database on launch like this:

您可以像这样在启动时擦除数据库:

[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];

回答by Kirit Vaghela

Just increment the schema version

只需增加架构版本

Realm will automatically detect new properties and removed properties

Realm 会自动检测新的属性和移除的属性

var 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: 2,

            // 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
                }
        })


        do{
            realm = try Realm(configuration: config)

            print("Database Path : \(config.fileURL!)")
        }catch{
            print(error.localizedDescription)
        }