RestKit 0.20:在 JSON 中使用动态扁平化层次结构

Posted

技术标签:

【中文标题】RestKit 0.20:在 JSON 中使用动态扁平化层次结构【英文标题】:RestKit 0.20: flattening the hierarchy with dynamic in JSON 【发布时间】:2013-05-31 06:37:42 【问题描述】:

我正在使用 RestKit 0.20,在将包含动态键的层次结构的 JSON 映射到一个对象时遇到问题。

JSON 如下所示:


    "id": 42,
    "name": "Name of this entity",
    "specialDataMap": 
        "2091:10": 
            "id": 2091,
            "type": "10",
            "value": "1'509.49",
            "name": "Name of special data type 10"
        ,
        "2091:02" 
            "id": 2091,
            "type": "02",
            "value": "5.5543",
            "name": "Name of special data type 02"
        
    

并且应该使用 RestKit 映射到这样的对象:

@interface InfoPoint : NSManagedObject

@property (nonatomic, retrain) NSString* identifier;
@property (nonatomic, retrain) NSString* name;
@property (nonatomic, retrain) NSString* valueOfType10;
@property (nonatomic, retrain) NSString* valueOfType02;

@end

如您所见,我不想创建关系并将特殊数据存储到单独的对象中。这没有任何意义。 我想像所有其他属性一样将嵌套属性分配到 InfoPoint 对象中。通常这适用于嵌套对象的关键路径,但此路径包含动态部分:“2091:10”是 id 和 id 可能更改的类型的组合(不是我的“原始”想法,但我有消费它)。

我在 RestKit 文档中阅读了有关 Handling Dynamic Nesting Attributes 的信息。但我没有发现这是否以及如何与嵌套属性一起使用。

----- 添加为对评论/问题的回复:----

我也试过Dynamic Object Mapping。但它不起作用,因为 RestKit 似乎对 @"self" 目的地有问题:

RKEntityMapping* type10Mapping = [RKEntityMapping mappingForEntityForName:@"InfoPoint" inManagedObjectStore:objectStore];
[type10Mapping addAttributeMappingsFromDictionary:@
 @"value": @"valueOfType10"];

RKDynamicMapping* dynamicMapping = [[RKDynamicMapping alloc] init];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"specialDataMap" toKeyPath:@"self" withMapping:dynamicMapping]];

[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) 
    if ([[representation valueForKeyPath:@"type"] isEqualToString:@"10"]) 
        return type10Mapping;
    
    return nil;
]; 

【问题讨论】:

您尝试过基于块的动态对象映射吗?如果您的键总是不同的,则需要动态创建映射。 是的,我尝试使用动态对象映射。我将我的代码添加到问题中。我想我在@"self" 上遇到了和以前一样的问题。 【参考方案1】:

您对动态映射的尝试不正确。您应该将动态映射提供给响应描述符。然后,动态映射应根据它在响应中找到的键创建并返回适当的映射。类似的东西(手写):

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

[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) 

    RKEntityMapping* typeMapping = [RKEntityMapping mappingForEntityForName:@"InfoPoint" inManagedObjectStore:objectStore];
    [typeMapping addAttributeMappingsFromDictionary:@
        @"id" : @"identifier",
        @"name": @"name",];

    NSDictionary *types = [representation valueForKeyPath:@"specialDataMap"];

    for (NSString *key in types) 
        NSDictionary *type = [[types objectForKey:key] objectForKey:@"type"];
        if ([type isEqualToString:@"10"]) 
            [typeMapping addAttributeMappingsFromDictionary:@
                [NSString stringWithFormat:@"specialDataMap.%@.value", key]: @"valueOfType10"];
         else if ...
    

    return typeMapping;
]; 

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

【讨论】:

有效!我没想过以这种方式使用动态映射。虽然我用 RKMappingTest 编写了映射测试,但这个解决方案似乎无法使用它,因为目标实体没有被创建,RestKit 也没有在标识符上找到现有实体。

以上是关于RestKit 0.20:在 JSON 中使用动态扁平化层次结构的主要内容,如果未能解决你的问题,请参考以下文章

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

Restkit 0.20 对象在获取 json 响应后未映射

RestKit 0.20 使用 nsdata 发布数组 Json

使用 RESTKIT 0.20 映射未命名值的 JSON 数组

RestKit 0.20 映射问题(使用来自 API 的 JSON)

你如何在 RestKit 0.20 中使用 RKDotNetDateFormatter?