使用 RestKit 将 JSON“关联数组”映射到 CoreData

Posted

技术标签:

【中文标题】使用 RestKit 将 JSON“关联数组”映射到 CoreData【英文标题】:Map JSON "Associative array" into CoreData with RestKit 【发布时间】:2013-06-06 07:13:25 【问题描述】:

我需要用 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 执行此类映射?

【问题讨论】:

【参考方案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]];

【讨论】:

【参考方案2】:

您需要使用动态映射,该映射是专门为字典中接收到的键创建的。您没有说目标对象是什么或您的映射是什么,所以这是一个一般示例(对于 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]];

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

【讨论】:

第二个键处理时出现异常“无法为 keyPath 名称添加映射,一个已经存在...”。 您需要根据要映射到的内容进行一些更改,以上只是该方法的一个示例。如果 JSON 是完整的内容,这将很困难,因为您需要将所有内容映射到单个对象中。您可能还想在映射目标中使用键并处理模型类中的传入数据。 好的,我找到了解决方案。感谢起点!我会在延迟 6 小时后发布我的答案)

以上是关于使用 RestKit 将 JSON“关联数组”映射到 CoreData的主要内容,如果未能解决你的问题,请参考以下文章

Restkit:来自 JSON parentId 的映射关系

如何使用带有 RKObjectMapping 的 RestKit 0.24 将本地 JSON 字符串映射到对象?

使用 RestKit 映射的 JSON Post 后 TableView 不刷新

在 RestKit 映射它之前访问 JSON 响应

RestKit 2.0 - 将 json 数组映射到实体关系会丢失数组序列

使用 RestKit 0.20 映射时在 JSON 中向上遍历