将属性从NSNumber转换为CoreData实体中的NSString - LightWeightMigration

时间:2017-10-23 15:12:34

标签: ios objective-c xcode9 core-data-migration

我尝试使用目标C中的轻量级迁移将NSNumber迁移到NSString属性。版本0 enter image description here

第2版

enter image description here

我已将核心数据模型当前版本更改为2

enter image description here

由于它在轻量级迁移中无法解决,我尝试使用CoreDataMapping Model和NSEntity迁移策略,如下所示。 enter image description here

创建了NSEntityMigrationPolicy的子类并尝试了下面的代码

@interface SampleMigrationV1toV2 : NSEntityMigrationPolicy

@end

#import "SampleMigrationV1toV2.h"

@implementation SampleMigrationV1toV2

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
{
    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName] inManagedObjectContext:[manager destinationContext]];

    // Copy all the values from sInstance into newObject, making sure to apply the conversion for the string to int when appropriate. So you should have one of these for each attribute:
    [newObject setValue:[sInstance valueForKey:@"number"] forKey:@"number"];

    [manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
    return YES;
}
@end

在持久协调员中,我已将NSInferMappingModelAutomaticallyOption更改为NO,如下所示,

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"CoreDataMigrationPolicty.sqlite"];

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

    NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:NO] forKey:NSInferMappingModelAutomaticallyOption];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
    {
        //NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return persistentStoreCoordinator;
}

做完所有这些事后,我得到的错误就像"错误域= NSCocoaErrorDomain代码= 134110"(null)" UserInfo = {NSUnderlyingException =无法使用userInfo字典为名为(CoreDataMigrationPolicty.SampleMigrationV1toV2)的类创建映射策略

未创建/调用映射模型。是更正核心数据中属性数据类型的正确方法吗?有没有其他方法来解决此问题而不崩溃/重新安装应用程序。

1 个答案:

答案 0 :(得分:0)

最后我发现了错误,我从这个答案中做了什么。 Core Data Migration: Attribute Mapping Value Expression

问题在于我在映射模型属性中提到的表达式。 语法是FUNCTION($ entityPolicy,“convertNumberToString:”,$ source.number),函数定义类似于

#import "SampleMigrationV1toV2.h"

@implementation SampleMigrationV1toV2

-(NSString *)convertNumberToString:(NSNumber *)number{
    return  [number stringValue];
}
@end

Mention Custom policy name(i.e.SampleMigrationV1toV2) on clicking Entity Mapping SampleToSample in

Enter the expression "FUNCTION($entityPolicy, "convertNumberToString:" , $source.number)" on clicking the attribute you want to migrate

FUNCTION($ entityPolicy,“convertNumberToString:”,$ source.number):

$ entityPolicy获取相应的MappingPolicy(即SampleMigrationV1toV2),如我们在EntityMapping“SampleToSample”中提到的那样,函数“convertNumberToString:”通过获取输入值$ source.Number将数字迁移到字符串