ios RLMException,对象类型需要迁移

tcomlyy6  于 2023-03-24  发布在  iOS
关注(0)|答案(8)|浏览(200)

我有一个对象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.'

下面是我的代码:

import Foundation
import Realm

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

aor9mmx11#

只要您尚未发布应用,您只需删除应用并重新运行即可。

每次更改Realm对象的属性时,现有的数据库就会变得与新数据库不兼容。
只要你还在开发阶段,你可以简单地从模拟器/设备中删除应用程序,然后重新启动它。

稍后,当您的应用发布后,您更改了对象的属性,您必须实现迁移到新的数据库版本。

要实际执行迁移,您需要实现一个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()

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

zazmityj

zazmityj2#

删除应用程序并重新安装并不是一个好的做法。我们应该在开发过程中从第一次遇到迁移需求时就加入一些迁移步骤。SilentDirge提供的链接很好:领域迁移文档,其中给出了处理不同情况的很好的示例。
对于最小的迁移任务,上面链接中的以下代码片段可以自动执行迁移,并将与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()
4xy9mtcn

4xy9mtcn3#

下面的代码是为我工作

- (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;
}

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

tjrkku2a

tjrkku2a4#

只需递增schema版本即可

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

pb3skfrl5#

修改后的数据库与保存的数据库不再兼容,这就是需要迁移的原因。您可以选择删除旧的数据库文件并重新启动(如果您处于初始开发阶段,则效果很好),或者如果您处于实时状态,则执行迁移。
您可以通过定义模式版本并在Realm配置中提供数据库迁移“脚本”来完成此操作。整个过程记录在此处(沿着代码示例):这里

a11xaf1n

a11xaf1n6#

你可以像这样在启动时删除数据库:

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

kkbh8khc7#

如果在递增schemaVersion后仍出现此错误,请仔细检查是否在App Delegate中更新schema版本之前调用了任何Realm对象
在我的例子中,我试图在执行代码迁移语句之前访问App Delegate中的Realm Object。

迁移代码始终写在App Delegate(DidfinishLaunchingWithOptions)的第一行,这样比较安全。

a11xaf1n

a11xaf1n8#

如果您对领域进行“Any”更改,则会收到迁移错误。
要解决此问题:
1.关闭Xcode
1.在你的终端上运行以下代码:rm -rf ~/Library/Developer/Xcode/DerivedData/
1.重新打开Xcode并编译。
1.问题已修复这将删除导致错误的Xcode数据。
每次你改变一些与“领域”有关的东西时,这样做,你就会重新启动和运行。

相关问题