bry*_*ark 11 iphone core-data core-data-migration ios simperium
我有一个iPhone应用程序,它使用多对多关系将标签和注释链接在一起.我目前正在使用Core Data的"关系"功能来完成此任务,但我想迁移到使用连接表.
这是我的挑战:我想从旧模型迁移到连接表模型,我需要弄清楚如何执行数据迁移.
有什么好的例子说明如何做到这一点?
更新:我在这里澄清我的问题,以帮助解决这里发生的事情:我想尝试使用Simperium来支持我们的应用程序,但是Simperium不支持多对多关系(!).
作为我正在尝试做的一个例子,让我们以iPhoneCoreDataRecipes应用程序为例.
以下是我的核心数据方案目前的类似内容:
......这就是我要过渡到的地方:
我如何从一个到另一个,并带来数据?
Apple的Core Data Migration文档非常稀疏,我没有看到任何有用的演练来使用NSEntityMapping或NSMigrationManager子类来完成工作.
小智 25
这是基本过程:
创建数据模型的版本化副本.(选择模型,然后选择编辑器 - >添加模型版本)
对数据模型的新副本进行更改
将新数据模型的副本标记为当前版本.(单击顶级xcdatamodel项,然后在文件检查器中将"Versioned Data Model"部分下的"Current"条目设置为您在步骤1中创建的新数据模型.
更新模型对象以添加RecipeIngredient实体.同时使用您在步骤2中为RecipeIngredient实体创建的新关系替换配方和成分实体上的成分和配方关系.(两个实体都添加了这个关系.我称之为recipeIngredients)显然,无论你在旧代码中创建从feed到recipe的关系,你现在都需要创建一个RecipeIngredient对象..但这超出了这个答案的范围.
在模型之间添加一个新的映射(文件 - >新文件...->(核心数据部分) - >映射模型.这将为您自动生成几个映射.RecipeToRecipe,IngredientToIngredient和RecipeIngredient.
删除RecipeIngredient映射.同时删除它为RecipeToRecipe和IngredientToRecipe(或在步骤2中称为它们的任何内容)提供的recipeIngredient关系映射.
将RecipeToRecipe Mapping拖动到映射规则列表中的最后一个.(这很重要,因此我们确保在食谱之前迁移成分,以便我们可以在迁移食谱时将它们链接起来.)迁移将按迁移规则列表的顺序进行.
为RecipeToRecipe映射设置自定义策略"DDCDRecipeMigrationPolicy"(这将覆盖Recipes对象的自动迁移,并为我们提供一个可以执行映射逻辑的钩子.
通过为配方子类化NSEntityMigrationPolicy创建DDCDRecipeMigrationPolicy以覆盖createDestinationInstancesForSourceInstance(请参阅下面的代码).这将为每个食谱调用一次,这将让我们创建食谱对象,以及将它链接到成分的相关RecipeIngredient对象.我们将在步骤5中通过Xcode自动为我们创建的映射规则自动迁移Ingredient.
无论您在何处创建持久对象存储(可能是AppDelegate),请确保将用户字典设置为自动迁移数据模型:
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, nil]
error:&error])
{
}
Run Code Online (Sandbox Code Playgroud)
食谱的子类NSEntityMigrationPolicy
#import <CoreData/CoreData.h>
@interface DDCDRecipeMigrationPolicy : NSEntityMigrationPolicy
@end
Run Code Online (Sandbox Code Playgroud)
*覆盖DDCDRecipeMigrationPolicy.m中的createDestinationInstancesForSourceInstance*
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{
NSLog(@"createDestinationInstancesForSourceInstance : %@", sInstance.entity.name);
//We have to create the recipe since we overrode this method.
//It's called once for each Recipe.
NSManagedObject *newRecipe = [NSEntityDescription insertNewObjectForEntityForName:@"Recipe" inManagedObjectContext:[manager destinationContext]];
[newRecipe setValue:[sInstance valueForKey:@"name"] forKey:@"name"];
[newRecipe setValue:[sInstance valueForKey:@"overview"] forKey:@"overview"];
[newRecipe setValue:[sInstance valueForKey:@"instructions"] forKey:@"instructions"];
for (NSManagedObject *oldIngredient in (NSSet *) [sInstance valueForKey:@"ingredients"])
{
NSFetchRequest *fetchByIngredientName = [NSFetchRequest fetchRequestWithEntityName:@"Ingredient"];
fetchByIngredientName.predicate = [NSPredicate predicateWithFormat:@"name = %@",[oldIngredient valueForKey:@"name"]];
//Find the Ingredient in the new Datamodel. NOTE!!! This only works if this is the second entity migrated.
NSArray *newIngredientArray = [[manager destinationContext] executeFetchRequest:fetchByIngredientName error:error];
if (newIngredientArray.count == 1)
{
//Create an intersection record.
NSManagedObject *newIngredient = [newIngredientArray objectAtIndex:0];
NSManagedObject *newRecipeIngredient = [NSEntityDescription insertNewObjectForEntityForName:@"RecipeIngredient" inManagedObjectContext:[manager destinationContext]];
[newRecipeIngredient setValue:newIngredient forKey:@"ingredient"];
[newRecipeIngredient setValue:newRecipe forKey:@"recipe"];
NSLog(@"Adding migrated Ingredient : %@ to New Recipe %@", [newIngredient valueForKey:@"name"], [newRecipe valueForKey:@"name"]);
}
}
return YES;
}
Run Code Online (Sandbox Code Playgroud)
我在Xcode和示例Xcode项目中发布了一个设置图片,但我似乎没有任何关于堆栈溢出的声誉点......所以它不会让我.我也会把这个发布到我的博客上.bingosabi.wordpress.com/.
另请注意,Xcode核心数据模型映射的东西有点片状,偶尔需要一个"干净",良好的Xcode rester,模拟器弹跳或上述所有工作.
归档时间: |
|
查看次数: |
3312 次 |
最近记录: |