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
RLMException, Migration is required for object type
提问by shahin ali agharia
I have an object NotSureItem
in which I have three properties title
whose name is renamed from text
and textDescription
which I had added later and a dateTime
property. 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
的名字是从更名text
和textDescription
我已经后来添加和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 schemaVersion
in 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 disFinishLaunchWithOptions
method:
对于最小迁移任务,上面链接中的以下代码片段可以自动执行迁移,并与 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
回答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)
}