【问题标题】:Can't map an array of objects for NSManagedObject in RestKit无法在 RestKit 中为 NSManagedObject 映射对象数组
【发布时间】:2014-02-14 15:51:23
【问题描述】:

我有 User 类,它是 NSManagedObject 子类:

@interface User : NSManagedObject

  @property (nonatomic, retain) NSString * about;
  @property (nonatomic, retain) NSString * contactAddress;
  @property (nonatomic, retain) NSString * contactEmail;
  @property (nonatomic, retain) NSString * hobbies;
  @property (nonatomic, retain) NSArray* jobExperience;
  @property (nonatomic, retain) NSString * name;
  @property (nonatomic, retain) NSString * surname;
@end

如您所见,该对象具有对象JobExperience 的NSArray 属性。 JobExperience定义如下:

@interface JobExperience : NSObject <NSCoding>

 @property (nonatomic,strong) NSString* position;
 @property (nonatomic,strong) NSString* organization;
 @property (nonatomic,strong) NSString* dateFrom;
 @property (nonatomic,strong) NSString* dateTo;
 @property (nonatomic,strong) NSString* website;
 @property (nonatomic,strong) NSString* location;
 @property (nonatomic,strong) NSString* jobDescription;
@end

在数据模型中,我有一个实体User,其中jobExperience 属性定义为transformable。这就是我在其中实现 NSCoding 方法的原因。 这是我对User 的映射:

 _sharedUserProfileMapping = [RKObjectMapping mappingForClass:[User class]];
    [_sharedUserProfileMapping addAttributeMappingsFromArray:@[
                                                               @"name", @"surname",
                                                               @"hobbies", @"interests",
                                                       @"contact_address", @"contact_email"
                                                              ]];

    RKObjectMapping* mappingForJobExperience = [RKObjectMapping mappingForClass:[JobExperience class]];
    [mappingForJobExperience addAttributeMappingsFromArray:@[
                                                             @"location",
                                                             @"website", @"organization" ,
                                                             @"position"  ,
                                                             @"date_from", @"date_to"
                                                             ]];

    [mappingForJobExperience addAttributeMappingsFromDictionary:@{@"description": @"jobDescription"}];

    [_sharedUserProfileMapping addRelationshipMappingWithSourceKeyPath:@"job_experience" mapping:mappingForJobExperience];

如您所见,我添加了关系映射。当User 只是一个NSObject 子类时,都完美映射了!!!但是当我创建 NSManagedObject 子类时,我遇到了一个异常:

NSManagedObject 映射一对多关系。即将通过 mutable[Set|Array]ValueForKey 应用值 restkit.object_mapping:RKMappingOperation.m:726 将 NSArray 关系对象从 keyPath 'job_experience' 映射到 'jobExperience'。价值: ( "", “” ) * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“实体“用户”的 NSManagedObjects 不支持 -mutableArrayValueForKey:属性“jobExperience” * 首先抛出调用栈:

只是为了完美地阐明其他属性映射。问题只在于这个JobExperience 对象数组。

【问题讨论】:

    标签: ios objective-c cocoa-touch core-data restkit


    【解决方案1】:

    您可能会陷入此处未实施的领域。具有托管对象数组的外部对象有效(IIRC),但根据您的描述和外部托管对象以及对象数组不起作用。您实际上并没有显示有效和无效的不同映射,这无济于事......

    RestKit 应该对目标数据类型进行内省以决定做什么。也许这不适用于这种情况,因为它提供了关系规范,它可能会假设目标是核心数据关系。

    无论如何,拥有一组自定义对象的托管对象是不常见的。通常您会使用 2 个托管对象和实体之间的关系。这更有意义,并在运行时提供了更多的表现力和效率。这是我推荐的。

    您可能需要设置mappingForJobExperience.forceCollectionMapping = YES; 才能使其工作(猜测)。

    【讨论】:

    • 'forceCollectionMapping = YES' - 这没有帮助。外部对象是什么意思?所以你对此没有任何解决方案?但在未来,除了 jobExperience 之外,还会添加更多对象,例如 UserSkillUserEducation 等等。我应该为它们创建一个 NSManagedObject 并与User 建立关系?
    【解决方案2】:

    RestKit 隐含地假定建模为数组或 NSManagedObject 中的集合的一对多关系映射到 CoreData 实体。一种解决方案是先前的答案提出的:将您的数组属性建模为一个单独的实体。如果这对您的设计不切实际,并且您确实希望将该属性保留为可转换的,则可以覆盖mutableArrayValueForKey。这可能是适合您的初始示例的可能实现:

    - (NSMutableArray *) mutableArrayValueForKey:(NSString *)key
    {
        if ( [key isEqualToString: @"jobExperience"] )
        {
            NSMutableArray * mutableJobExperience = [NSMutableArray array];
            if ( self.jobExperience != nil )
            {
                mutableJobExperience.array = self.jobExperience;
            }
            self.jobExperience = mutableJobExperience;
            return mutableJobExperience;
        } else {
            return [super mutableArrayValueForKey: key];
        }
    }
    

    这个简单实现的缺点是我们将jobExperience 变成了一个可变数组。在完全映射结果之后,这可能会在您的代码的稍后阶段修复。

    另一个解决方案是修补 RestKit 以在这种情况下表现不同。如果无法获得可变代理,我建议修改RKMappingOperation 的方法- (BOOL)mapCoreDataToManyRelationshipValue:(id)valueForRelationship withMapping:(RKRelationshipMapping *)relationshipMapping 以返回NO。这应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多