使用RestKit进行嵌套对象映射

时间:2014-02-01 22:07:36

标签: ios objective-c json restkit restkit-0.20

我正在尝试将JSON映射到一个对象结构中,这是一个小小的问题:

- Group
  + label
  + type
  + children
    - childname1
       + label
       + type
       + value

    - childname2
       + label
       + type
       + value

我有Group

@interface CameraGroup : NSObject
@property (nonatomic, copy) NSString *label;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSDictionary *children;
@end

Child

@property (nonatomic, copy) NSString *label;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy) NSString *value;

我的JSON如下:

{
    "actions": {
        "label": "Action List",
        "type": "section",
        "children": {
            "action1": {
                "label": "This is action1",
                "type": "toggle",
                "value": 0
            },
            "action2": {
                "label": "This is action2",
                "type": "range",
                "value": 0
            },
            "action3": {
                "label": "This is action3",
                "type": "toggle",
                "value": 0
            }
        }
    }
}

我正试图以一个Object of Group结束,使用RestKit持有带有键值对操作的NSDictionary(children)(例如action1 =键和标签,类型和值的子对象)。

我正在使用以下代码段,但总是最终得到一个空的子对象:

RKObjectMapping *mappingChild = [RKObjectMapping mappingForClass:[Child class]];
  [mappingSetting addAttributeMappingsFromDictionary:@{
                                                @"label": @"label",
                                                @"type":  @"type",
                                                @"value": @"value"
                                                }];

  RKObjectMapping *mappingGroup = [RKObjectMapping mappingForClass:[Group class]];
  [mappingGroup addAttributeMappingsFromDictionary:@{
                                                       @"label": @"label",
                                                       @"type":  @"type"
                                                       }];
  [mappingGroup addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:mappingSetting]];


  NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); 
  RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mappingGroup method:RKRequestMethodAny pathPattern:@"/action" keyPath:@"actions" statusCodes:statusCodes];

  NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://192.168.178.1:1337/actions"]];
  RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];
  [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
    Group *group = [result firstObject];
    NSLog(@"Mapped the group: %@ of type %@ with children %i", article.label, article.label, [group.children count]);
  } failure:^(RKObjectRequestOperation *operation, NSError *error) {
    NSLog(@"Failed with error: %@", [error localizedDescription]);
  }];
  [operation start];

那么有没有办法如何映射NSDictionary部分而不知道“action1”被命名为“action1”??

1 个答案:

答案 0 :(得分:4)

在玩完之后我发现了一个似乎有用的解决方案。 responseDescriptor获取具有关系映射的GroupdynamicMapping的映射,该映射遍历所有子节点并映射childMapping

RKObjectMapping *mappingChild = [RKObjectMapping mappingForClass:[Child class]];

  [mappingSetting addAttributeMappingsFromDictionary:@{
                                                       @"label" : @"label",
                                                       @"type" : @"type",
                                                       @"value" : @"value"
                                                       }];

  RKDynamicMapping* dynamicMapping = [RKDynamicMapping new];
  [dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {

    NSArray *keys = [representation allKeys];

    RKObjectMapping *dataMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];

    for (NSString *key in keys) {
      [dataMapping addRelationshipMappingWithSourceKeyPath:key mapping:mappingChild];
    }

    return dataMapping;

  }];

  RKObjectMapping *mappingGroup = [RKObjectMapping mappingForClass:[Group class]];
  [Group addAttributeMappingsFromDictionary:@{
                                                     @"label": @"label",
                                                     @"type":  @"type"
                                                     }];

  [Group addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"children" toKeyPath:@"children" withMapping:dynamicMapping]];







  NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); 
  RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mappingGroup
                                                                                          method:RKRequestMethodAny
                                                                                     pathPattern:@"/actions"
                                                                                         keyPath:@"actions"
                                                                                     statusCodes:statusCodes];