Restkit 0.2返回RKMappingSourceObject类型对象为一对多类型关系

时间:2014-02-10 09:48:49

标签: objective-c core-data restkit restkit-0.20

我正在尝试在我的应用程序中映射JSON数组。我面临的问题是,我得到的是类型为RKMappingSourceObject的对象,而不是获取类型为NSString的对象。

回复的形式为

{
         message =     {
            Appetite =         {
                    Breakfast = 4;
                    Dinner = 4;
                    Lunch = 4;
                };
        PainSymptom =         {
       Aching = 1;
                AtRest = 0;
                Awakes = 0;
                Burning = 0;
                Cramping = 0;
                    Location =             (
                        Head,
                        "Right Upper Leg",
                        "Left Upper Leg",
                        "Left Ankle/Foot",
                        "Right Ankle/Foot",
                        "Mid Back",
                        "Upper Back",
                        Tailbone
                    );
                };
        }
}

我的核心数据类是:

DTAttribute.h

@interface DTAttribute : NSManagedObject

@property (nonatomic, strong) NSString * attribute;
@property (nonatomic, strong) DTPainSymptom *painSymptom;

@end

DTAttribute.m

@implementation DTAttribute

@dynamic attribute;
@dynamic painSymptom;

@end

DTPainSymptom.h

@interface DTPainSymptom : NSManagedObject

@property (nonatomic, retain) NSNumber * aching;
@property (nonatomic, retain) NSNumber * atRest;
@property (nonatomic, retain) NSNumber * awakes;
@property (nonatomic, retain) NSNumber * burning;
@property (nonatomic, retain) NSNumber * cramping;
@property (nonatomic, retain) DTMyDay *myDay;
@property (nonatomic, retain) NSSet *painLocations;
@end

@interface DTPainSymptom (CoreDataGeneratedAccessors)

- (void)addPainLocationsObject:(DTAttribute *)value;
- (void)removePainLocationsObject:(DTAttribute *)value;
- (void)addPainLocations:(NSSet *)values;
- (void)removePainLocations:(NSSet *)values;

@end

DTPainSymptom.m

@implementation DTPainSymptom

@dynamic aching;
@dynamic atRest;
@dynamic awakes;
@dynamic burning;
@dynamic cramping;
@dynamic myDay;
@dynamic painLocations;

@end

DTMyDay.h

@interface DTMyDay : NSManagedObject

@property (nonatomic, retain) DTPainSymptom *painSymptom;

@end

DTMyDay.m

@implementation DTMyDay

@dynamic painSymptom;

@end

映射:

@implementation DTMyDay(Mapping)

+ (id) mapping {
  RKEntityMapping* myDayMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTMyDay class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];

  RKEntityMapping* attributeMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTAttribute class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
  [attributeMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:@"attribute"]];

  //Pain Symptom
  RKEntityMapping* painSymptomMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass([DTPainSymptom class]) inManagedObjectStore:[[RKObjectManager sharedManager] managedObjectStore]];
  [painSymptomMapping addAttributeMappingsFromDictionary:@{
                                                           @"Awakes": @"awakes",
                                                           @"AtRest": @"atRest",
                                                           @"Burning": @"burning",
                                                           @"Cramping": @"cramping",
                                                           @"Aching": @"aching",
                                                           }];
  [painSymptomMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"Location"
                                                                                     toKeyPath:@"painLocations"
                                                                                   withMapping:attributeMapping]];


  [myDayMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"message.PainSymptom"
                                                                               toKeyPath:@"painSymptom"
                                                                             withMapping:painSymptomMapping]];

  NSDateFormatter* dateFormatter = [NSDateFormatter new];
  [dateFormatter setDateFormat:@"yyyy-MM-dd"];
  myDayMapping.dateFormatters = [NSArray arrayWithObject: dateFormatter];
  return myDayMapping;
}


+ (id)responseDescriptor:(NSString *)pathPattern {
  RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:[self mapping] pathPattern:pathPattern keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
  return responseDescriptor;
}

@end

此处的问题是未正确映射与message.PainSymptom.Location对应的值数组。我在painLocations类中获取了与DTMyDay对应的DTAttribute类型对象数组。但是,当我尝试访问painLocations数组中每个DTAttribute类的属性属性时,我得到类型为RkMappingSourceObject的对象而不是类型NSString

我很抱歉这段巨大的代码,但现在我真的不知道该怎么做。

enter image description here

这导致了一个问题因为我将dtAttribute.attribute发送给一个方法,它返回给我NSNotFound,因为传递的对象是RKMappingSourceObject类型:

#define BODY_PARTS_NAMES @"Head", @"Right Shoulder", @"Neck", @"Left Shoulder", @"Right Chest", @"Left Chest", @"Right Arm", nil

- (BodyPart)bodyPartStringToEnum:(NSString *)strVal
{
    NSArray *bodyPartsArray = [[NSArray alloc] initWithObjects:BODY_PARTS_NAMES];
    NSUInteger index = [bodyPartsArray indexOfObject:strVal];

    return index;
}

2 个答案:

答案 0 :(得分:0)

RKMappingSourceObject是RestKit中使用的代理对象,用于在映射过程中处理内省问题和元数据。由于它是一个代理并转发所有方法调用,因此只需在映射结束时返回。通常这不会引起问题。

我没想到它会导致基于您的代码的问题,但显然比较方法中的某些东西不起作用。 RKMappingSourceObject应转发class请求和'普通'方法调用...

RKMappingSourceObject有一个object方法,问题是如何知道你应该调用它(因为该类应该作为NSString的某个子类返回)。我会看一个讨厌的事情:

- (BodyPart)bodyPartStringToEnum:(NSString *)strVal
{
    if ([strVal respondsToSelector:@selector(object)]) {
        strVal = [strVal object];
    }

    NSArray *bodyPartsArray = [[NSArray alloc] initWithObjects:BODY_PARTS_NAMES];
    NSUInteger index = [bodyPartsArray indexOfObject:strVal];

    return index;
}

我不喜欢但希望将来可以工作并与将来(删除)代理对象的潜在更改兼容。或者,调试以确定比较失败的原因并查看更改代理实现。

答案 1 :(得分:0)

RKMappingSourceObject转换为NSString的另一种方式:

NSString *realString = [NSString stringWithString:stringProxy];

其中stringProxyRKMappingSourceObject的实例。