Ios RLMEException,对象类型需要迁移
我有一个对象Ios RLMEException,对象类型需要迁移,ios,swift,realm,Ios,Swift,Realm,我有一个对象NotSureItem,其中我有三个属性title,它们的名称是从我后来添加的text和textDescription重命名的,还有一个dateTime属性。现在,当我要运行我的应用程序时,当我想向这些属性添加内容时,它会崩溃。它显示以下语句 'Migration is required for object type 'NotSureItem' due to the following errors: - Property 'text' is missing from latest
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.'
这是我的密码:
import Foundation
import Realm
class NotSureItem: RLMObject {
dynamic var title = "" // renamed from 'text'
dynamic var textDescription = "" // added afterwards
dynamic var dateTime = NSDate()
}
只要你没有发布你的应用,你就可以删除你的应用,然后再次运行 每次更改领域对象的属性时,现有数据库都与新数据库不兼容 只要您仍处于开发阶段,您就可以从模拟器/设备中删除应用程序,然后重新启动 稍后,当您的应用程序发布后您更改对象的属性时,您必须实现到新数据库版本的迁移 要实际执行迁移,需要实现领域迁移块。通常,您会将块添加到
应用程序(应用程序:didFinishLaunchingWithOptions:)
:
var-configuration=Realm.configuration(
阴谋厌恶:1,
migrationBlock:{migration,oldSchemaVersion in
如果oldschemaversation<1{
//如果只是更改了模型属性的名称,则可以执行此操作
migration.renameProperty(onType:NotSureItem.className(),从“文本”到“标题”)
//如果要用某些值填充新属性,则必须枚举
//选择现有对象并设置新值
enumerateObjects(类型:NotSureItem.className()){oldObject,中的newObject
将text=oldObject![“text”]设为!字符串
newObject![“textDescription”]=“标题为\(文本)”
}
//如果添加了新属性或删除了属性,则不需要
//必须做任何事情,因为领域自动检测到
}
}
)
Realm.Configuration.defaultConfiguration=配置
//现在打开领域文件可以确保执行迁移
让我试试!领域()
每当您的方案更改时,您必须增加迁移块中的
schemaversation
,并更新块中所需的迁移。下面的代码对我有用
- (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;
}
-(BOOL)应用程序:(UIApplication*)应用程序使用选项完成启动:(NSDictionary*)启动选项
{
RLMRealmConfiguration*config=[RLMRealmConfiguration defaultConfiguration];
config.schemaVersion=2;
config.migrationBlock=^(RLMMiglation*迁移,uint64\u t旧模式){
//enumerateObjects:block:方法迭代
//在域文件中存储的每个“Person”对象上
[迁移枚举对象:Person.className]
块:^(RLMObject*oldObject,RLMObject*newObject){
//仅将“fullName”属性添加到架构版本为0的领域
if(oldschemaversation<1){
newObject[@“fullName”]=[NSString stringWithFormat:@“%@%@”,
oldObject[@“firstName”],
oldObject[@“lastName”];
}
//将“email”属性添加到架构版本为0或1的领域
if(oldschemaversation<2){
新对象[@“电子邮件”]=@;
}
}];
};
[RLMRealmConfiguration setDefaultConfiguration:config];
//现在我们已经更新了模式版本并提供了迁移块,
//打开过时的领域将自动执行迁移和
//打开这个领域将会成功
[RLMRealm defaultRealm];
返回YES;
}
更多信息:您修改的数据库与保存的数据库不再兼容,这就是需要迁移的原因。您可以选择删除旧的数据库文件并重新开始(如果您处于初始开发阶段,效果会很好),或者如果您处于活动状态,则执行迁移
您可以通过定义架构版本并在领域配置中提供数据库迁移“脚本”来实现这一点。整个过程都记录在这里(以及代码示例):您可以像这样在启动时擦除数据库:
[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];
删除应用程序并重新安装不是一个好做法。从我们第一次遇到迁移需求开始,我们就应该在开发过程中加入一些迁移步骤。SilentDirge给出的链接很好:,它为处理不同情况提供了很好的示例 对于最小迁移任务,上面链接中的以下代码段可以自动执行迁移,并将与AppDelegate的
disFinishLaunchWithOptions
方法一起使用:
let config=Realm.Configuration(
//设置新架构版本。该版本必须大于以前使用的版本
//版本(如果以前从未设置过架构版本,则版本为0)。
阴谋厌恶:1,
//设置使用打开域时自动调用的块
//低于上面设置的架构版本
migrationBlock:{migration,oldSchemaVersion in
//我们还没有迁移任何内容,所以oldSchemaVersion==0
if(oldschemaversation<1){
//无事可做!
//领域将自动检测新属性和删除的属性
//并将自动更新磁盘上的架构
}
})
//告诉领域将此新配置对象用于默认领域
Realm.Configuration.defaultConfiguration=config
//现在我们已经告诉Realm如何处理模式更改,打开文件
//将自动执行迁移
让我们试试!Realm()
只需增加架构版本
领域将自动检测新属性和删除的属性
var config=Realm.Configuration(
//设置新架构版本。该版本必须大于以前使用的版本
//版本(如果以前从未设置过架构版本,则版本为0)。
阴谋厌恶:2,
[[NSFileManager defaultManager] removeItemAtURL:[RLMRealmConfiguration defaultConfiguration].fileURL error:nil];
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)
}