0

我需要用 RestKit(iOS) 映射 JSON 关联的对象数组。它看起来像具有属性 135,145,423 的对象和上面的对象。

{
  "135": {
    "name" : "Object1",
    "property1" : "Value1",
    "anotherProperty1" : "Value2"
  },
  "145": {
    "name": "Object2",
    "property1" : "Value1",
    "anotherProperty1" : "Value2"
  },
  "423": {
    "name": "Object3",
    "property1" : "Value1",
    "anotherProperty1" : "Value2"
  }
}

我已经为有效的单个对象进行了映射。映射到 CoreData。我唯一的解决方案是将关联数组转换为普通数组并将编号转换为“id”字段,但我认为这不是优雅的解决方案。

是否有任何正确的方法可以直接使用 RestKit 执行此类映射?

4

2 回答 2

1

这是我的情况的解决方案。

NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful); // Anything in 2xx

// 1. Create dynamic mapping
RKDynamicMapping* dynamicMapping = [[RKDynamicMapping alloc] init];
// 2. Process every entry separately
dynamicMapping.forceCollectionMapping = YES;

// 3. Set mappings for every object
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
    // 4. Mapping to Core Data (Can be replaced with RKObjectMapping if there's no need of CodeData)
    RKEntityMapping *singleRouteMapping = [RKEntityMapping mappingForEntityForName:@"Object" inManagedObjectStore:managedObjectStore];
    // 5. Walking through all keys (but with dynamicMapping.forceCollectionMapping = YES) there'll be only one. It's better to refactor it.
    for (NSString *key in representation) {
        // 6. Set mappings for every property exect 'id'
        [singleRouteMapping addAttributeMappingsFromDictionary:@{
         [NSString stringWithFormat: @"%@.name", key]: @"name",
         [NSString stringWithFormat: @"%@.property1", key]: @"property1",
         [NSString stringWithFormat: @"%@.anotherProperty1", key]: @"anotherProperty1"
         }];
    }
    // 7. Map 'id' property at last
    [singleRouteMapping addAttributeMappingFromKeyOfRepresentationToAttribute: @"id"];

    return singleRouteMapping;
}];

RKResponseDescriptor *pluralDescriptor = [RKResponseDescriptor responseDescriptorWithMapping: dynamicMapping
    pathPattern: @"/api/objects"
    keyPath: nil
    statusCodes: statusCodes];

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.somesite.com/api/objects"]];
RKManagedObjectRequestOperation *operation = [[RKManagedObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[pluralDescriptor]];
于 2013-06-06T16:37:22.270 回答
0

您需要使用动态映射,其中映射是专门为字典中接收到的键创建的。您没有说目标对象是什么或您的映射是什么,所以这是一个通用示例(对于 Core Data,但可以更改为普通对象):

RKDynamicMapping* dynamicMapping = [[RKDynamicMapping alloc] init];

[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {

RKEntityMapping* typeMapping = [RKEntityMapping mappingForEntityForName:@"..." inManagedObjectStore:objectStore];

for (NSString *key in representation) {
    NSDictionary *type = [representation objectForKey:key];
    [typeMapping addAttributeMappingsFromDictionary:@{
            [NSString stringWithFormat:@"%@.name", key]: @"name"}];
}

return typeMapping;
}]; 

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:dynamicMapping
                                                                               pathPattern:...
                                                                                   keyPath:nil
                                                                               statusCodes:[NSIndexSet indexSetWithIndex:200]];

这基本上去掉了数字并将它们扔掉。如果需要,您可以通过配置动态映射来包含它们。

于 2013-06-06T07:30:53.577 回答