核心数据 - 默认迁移(手动) [英] Core Data - Default Migration ( Manual )

查看:150
本文介绍了核心数据 - 默认迁移(手动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读所有可能的博客和SO的主题 - 但仍然不知道发生了什么。
我还阅读了但仍然没有运气 - 他们的指南,默认迁移清楚,但不工作在我的情况。
我是iOS开发的新手,所以要温柔:)



这里是情况:
在我的应用程序(iOS),需要进行以下更改:



数据属性 - 已删除



title 属性需要从整数16更改为字符串。 title 属性 - 添加



这是什么导致我的问题。
我从当前的数据模型创建了新版本的数据模型,并修改了属性。



这里是应用程序的一些方法:

   - (NSManagedObjectModel *)managedObjectModel 
{
if(__managedObjectModel!= nil)
{
return __managedObjectModel;
}
NSURL * modelURL = [[NSBundle mainBundle] URLForResource:@AppwithExtension:@momd];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}

,然后

  / ** 
返回应用程序的持久存储协调器。
如果协调器不存在,则会创建它并将应用程序的存储添加到其中。
* /
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if(__persistentStoreCoordinator!= nil)
{
return __persistentStoreCoordinator;
}

NSURL * storeURL = [[self applicationDocumentsDirectory] ​​URLByAppendingPathComponent:@App.sqlite];
NSError * error = nil;

__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSLog(@当前版本是我们的.xcdatamodeld文件设置为?%@,[[self managedObjectModel] versionIdentifiers]);
NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
//注释为手动迁移[NSNumber numberWithBool:YES],NSInferMappingModelAutomaticallyOption,
nil] ;


if(![__ persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:& error])
{

NSLog (@未解决的错误%@,%@,错误,[错误userInfo]);
abort();
}

return __persistentStoreCoordinator
}

我试过轻量级迁移。它失败了

  reason =找不到迁移的映射模型
pre>

然后我做了以下只是尝试:使reportId属性回到它是什么(interger 16,保持模型中的其他两个变化轻量级迁移工作很好。



好吧,我想,它可能需要手动映射来处理数据类型更改。
所以,我创建了映射模型我试图将reportId设置为和source.reportId),关闭轻量级迁移。由于我是新的,我决定采取宝贝的步骤,不要使这个reportId Int> String更改只是和测试我的映射,它没有工作,同样的原因=找不到映射模型迁移我试图将reportId更改为字符串,因为它应该是相同的结果。它几乎看起来我我的映射模型完全被忽略,其实我已经尝试删除它 - 相同的结果相同的错误。
这里我错过了什么?

  ## EDIT ## 

到底,我已经下载了Mihai的应用程序(谢谢! )并开始玩弄它。
我修改了持久化存储协调器,以匹配默认迁移为


$ b

   - NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{
if(__persistentStoreCoordinator!= nil)
{
return __persistentStoreCoordinator;
}

NSURL * storeURL = [[self applicationDocumentsDirectory] ​​URLByAppendingPathComponent:@TestData.sqlite];

NSError * error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption,
nil];

if(![__ persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:& error])
{
NSLog(@Unresolved error% %@,error,[error userInfo]);
abort();
}

return __persistentStoreCoordinator;
}

我有一个错误,它基本上找到了正确的映射模型,并尝试匹配它,并给出非常有效的错误。
2012-02-07 10:47:39.246 TestData [2008:707] * 由于未捕获异常而终止应用程序NSInvalidArgumentException,原因:属性的不可接受的值类型: reportId;所需类型= NSString;给定类型= __NSCFNumber; value = 1。'



在我的例子中,我有一个dump,看起来像这样(只是日志的一小部分):

  Report =(< NSEntityDescription:0x1708d0>)name Report,managedObjectClassName Report,renamingIdentifier Report,isAbstract 0,superentity name(null),properties {\\\
action = \(),name动作,isOptional 1,isTransient 0,实体Report,renamingIdentifier动作,验证谓词(\\\\
),警告(\\\\
),versionHashModifier )\\\\
userInfo {\\\\
},attributeType 100,attributeValueClassName NSNumber,defaultValue 0 \; \\\
data = \(< NSAttributeDescription:0x1709e0>),名称数据, isTransient 0,实体报告,重命名标识符数据,验证谓词(\\\\
),警告(\\\\
),versionHashModifier(null)\\\\
userInfo {\\\\
},attributeType 700,attributeValueClassName NSString,defaultValue(null)\; \\\
reportId = \(),name reportId,isOptional 1,isTransient 0,entity Report,renamingIdentifier reportId,validation predicate(\\\\
),警告(\\\\
),versionHashModifier(null)\\\\
userInfo {\\\\
},attributeType 100,attributeValueClassName NSNumber,defaultValue 0 \; \\\
timestamp = \ < NSAttributeDescription:0x170ad0>),name timestamp,isOptional 1,isTransient 0,entity Report,renamingIdentifier timestamp,validation predicates(\\\\
),warnings(\\\\
),versionHashModifier(null)\\ n userInfo {\\\\
},attributeType 900,attributeValueClassName NSDate,defaultValue(null)\; \\\
type = \(< NSAttributeDescription:0x170990>),name类型,isOptional 1,isTransient 0,实体Report,renamingIdentifier类型,验证谓词(\\\\
),警告(\\\\
),versionHashModifier(null)\\\\
userInfo {\\\\
},attributeType 100,attributeValueClassName NSNumber,defaultValue 0 \; \ n},子实体{\ n},userInfo {\ n},versionHashModifier(null);
},fetch请求模板{
},reason =找不到迁移的映射模型},{



EDIT 2



我有'NSInvalidArgumentException',原因:'映射和源/目标模型之间的不匹配'源和目标模型和映射模型,一切看起来像它应该。
我即将放弃并愿意放弃该报表实体中的数据。有任何方法吗?



EDIT 3



所以,只是为了试试,我回滚我的模型,它在所有这疯狂之前,创建了新版本,只做了一个改变 - 掉了一个字段。然后我创建了映射模型,并尝试使用它。 - 相同的错误映射和源/目标模型之间不匹配 - 看起来生成的映射模型是不知何故,但看看它 - 我没有看到任何问题。

解决方案

借助我从这个问题我得到了解决你的问题。



我把一个演示应用程序基于默认主/详细模板与核心数据。当第一次运行时,确保在TestData.xcdatamodeld中选择了TestData模型。添加一些行,然后移动到TestData 2.xcdatamodel,迁移将进行适当的更改。



演示应用程序可以从此处


i've read all possible blogs and SO post on the subject - but still not sure what's going on. I've also read this but still no luck - their guide to Default migration kind of clear but doesn't work in my situation . I'm relatively new to iOS development, so be gentle :)

Here is the situation: on the entity called Report in my app (iOS), following changes need to happen:

data attribute - deleted

title attribute - added

reportId attribute need to be changed from Integer 16 to String. This is what causing my problems. I did created new version of the my data model from my current one and modifying attributes.

First here is some methods from the app:

- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"App" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

and then

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"App.sqlite"];
    NSError *error = nil;

    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSLog(@"Which Current Version is our .xcdatamodeld file set to? %@", [[self managedObjectModel] versionIdentifiers]);
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:  
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
//Commented for manual migration [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,  
                             nil];  


    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return __persistentStoreCoordinator
}

First i've tried lightweight migration. It failed with

reason=Can't find mapping model for migration

Then i did the following just to try: made reportId attribute back to what it was (interger 16, keeping other two changes in the model. Lightweight migration worked just fine.

Ok, i thought, it probably need to have manual mapping in order to handle data type change. So, i've created mapping model ( in which i've tried to set reportId to both "", and source.reportId ), turned off lightweight migration. Since i'm new to this, i've decided to take baby steps and don't make this reportId Int > String change just yet and test my mapping. And it didn't work. With same reason=Can't find mapping model for migration. I've tried to change reportId to String as it should be - same result. It almost looks to me that my mapping model is completely ignored. In fact i've tried to delete it - same result same error. What the hell i'm missing here ?

                      ## EDIT ##

Ok, i need to get to the bottom of this, I've downloaded the app that Mihai had put together ( thanks ! ) and started to play around with it. I've modified persistent store coordinator to match whatever i have for "Default Migration" to be this

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestData.sqlite"];

    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:  
                             [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                                                       nil]; 

    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return __persistentStoreCoordinator;
}

And i've got the error that totally make sense to me. It basically found right mapping model and try to match it and gave very valid error. 2012-02-07 10:47:39.246 TestData[2008:707] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "reportId"; desired type = NSString; given type = __NSCFNumber; value = 1.'

Where in my case i have dump that looks like this ( just a small part of the log ) :

   Report = "(<NSEntityDescription: 0x1708d0>) name Report, managedObjectClassName Report, renamingIdentifier Report, isAbstract 0, superentity name (null), properties {\n    action = \"(<NSAttributeDescription: 0x170a30>), name action, isOptional 1, isTransient 0, entity Report, renamingIdentifier action, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 100 , attributeValueClassName NSNumber, defaultValue 0\";\n    data = \"(<NSAttributeDescription: 0x1709e0>), name data, isOptional 1, isTransient 0, entity Report, renamingIdentifier data, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 700 , attributeValueClassName NSString, defaultValue (null)\";\n    reportId = \"(<NSAttributeDescription: 0x170a80>), name reportId, isOptional 1, isTransient 0, entity Report, renamingIdentifier reportId, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 100 , attributeValueClassName NSNumber, defaultValue 0\";\n    timestamp = \"(<NSAttributeDescription: 0x170ad0>), name timestamp, isOptional 1, isTransient 0, entity Report, renamingIdentifier timestamp, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 900 , attributeValueClassName NSDate, defaultValue (null)\";\n    type = \"(<NSAttributeDescription: 0x170990>), name type, isOptional 1, isTransient 0, entity Report, renamingIdentifier type, validation predicates (\\n), warnings (\\n), versionHashModifier (null)\\n userInfo {\\n}, attributeType 100 , attributeValueClassName NSNumber, defaultValue 0\";\n}, subentities {\n}, userInfo {\n}, versionHashModifier (null)";
}, fetch request templates {
}, reason=Can't find mapping model for migration}, {

EDIT 2

Got to the point where i have 'NSInvalidArgumentException', reason: 'Mismatch between mapping and source/destination models' - po both source and destination models and mapping models, everything looks like it should. I'm about to give up and willing to loose the data in that Report entity.. Is there any way of doing it ?

EDIT 3

So, just to try things out, i've rollback my model where it was before all this madness, created new version in which i've made only one change - dropped one field. And then i've created mapping model and try to use it. - Same error Mismatch between mapping and source/destination models - it looks like generated mapping model is bad somehow, but looking at it - i didn't see any issues.

解决方案

With the help i got from this question i got to solve your issue.

I have put together a demo app based on the default master/detail template with core data. When run it first time, make sure you have the "TestData" model selected in "TestData.xcdatamodeld". Add some rows, then move to "TestData 2.xcdatamodel" and the migration will make the proper changes.

The demo app can be downloaded from here

这篇关于核心数据 - 默认迁移(手动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆