Can't map an array of objects for NSManagedObject in RestKit

大兔子大兔子 提交于 2019-12-11 05:08:39

问题


I have User class which is NSManagedObject subclass:

@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

As you can see this object has an NSArray property of objects JobExperience. JobExperience defined as follows:

@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

In the data model I have one entity User where jobExperience attribute defined as transformable. That's why I implement NSCoding methods in it. Here is my mapping for 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];

As you can see I add relationship mapping. When User was just an NSObject subclass all mapped perfectly!!! But when I made it NSManagedObject subclass I got an exception:

Mapping a to-many relationship for an NSManagedObject. About to apply value via mutable[Set|Array]ValueForKey restkit.object_mapping:RKMappingOperation.m:726 Mapped NSArray relationship object from keyPath 'job_experience' to 'jobExperience'. Value: ( "", "" ) * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'NSManagedObjects of entity 'User' do not support -mutableArrayValueForKey: for the property 'jobExperience'' * First throw call stack:

And just for clarifying other attributes map perfectly. The problem only with this array of JobExperience objects.


回答1:


You could be falling into an area that isn't implemented here. An outer object with an array of managed objects works (IIRC), but from your description and outer managed object and an array of objects doesn't work. It doesn't help that you aren't actually showing the different mappings that do and don't work though...

RestKit should be introspecting on the destination data type to decide what to do. Perhaps that doesn't work for this situation as it is provided with a relationship spec, it may assume that the destination is a Core Data relationship.

In any case, it's unusual to have a managed object with an array of custom objects. Usually you would use 2 managed objects and a relationship between the entities. This makes more sense and provides more expressive power and efficiency at runtime. This is what I'd recommend.

It could be that you need to set mappingForJobExperience.forceCollectionMapping = YES; to make it work (a guess).




回答2:


RestKit implicitly presumes that a to-many relationship modelled as an array or a set in a NSManagedObject maps to a CoreData entity. One solution is what the previous answer proposed: model your array attribute as a separate entity. If that's impractical for your design and you really want to keep the attribute as a Transformable, you may overwrite mutableArrayValueForKey. This could be a possible implemention appropriate for your initial example:

- (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];
    }
}

The downside of this simple implementation is that we are turning jobExperience into a mutable array. That can probably be fixed at a later stage in your code, after results have been mapped completely.

Another solution would be to patch RestKit to behave differently in this situation. I would suggest to modify the method - (BOOL)mapCoreDataToManyRelationshipValue:(id)valueForRelationship withMapping:(RKRelationshipMapping *)relationshipMapping of RKMappingOperation to return NO if a mutable proxy cannot be obtained. That should do the trick.



来源:https://stackoverflow.com/questions/21319348/cant-map-an-array-of-objects-for-nsmanagedobject-in-restkit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!