4

我有一个如下所示的 JSON:

 { 
  "key1":[ 
  { 
    "desc":"key1decs.", 
    "duration":50; 
  },{ 
    "desc":"", 
    "duration":90; 
  },{ 
    "desc":"Kurz vor...", 
    "duration":30; 
  } 
 ], 
 "key2":[ 
  { 
    "desc":"key2decs.", 
    "duration":50; 
  },{ 
    "desc":"blabla", 
    "duration":90; 
  } 
] 
} 

我正在尝试进行映射。但是由于不同的未知/任意键,我被卡住了。我尝试在没有 KVC 的情况下进行映射,但它似乎不起作用。给我错误:keyPath 'key1.desc' 处的值转换失败。没有从 '__NSArrayI' 转换为 'NSString' 的策略。等等每个属性。我在网上看到没有 KVC 的映射不支持数组作为内部结构。请帮忙。什么是正确的方法?

编辑:实体:

@interface Sendung : NSObject

 @property (nonatomic, strong) NSString *description;
 @property (nonatomic, strong) NSNumber *duration;
 @property (nonatomic, strong) NSNumber *sendungkey;
@end;

控制器:

 RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[Sendung class]];
 mapping.forceCollectionMapping = YES;
[mapping mapKeyOfNestedDictionaryToAttribute:@"sendungkey"];
[mapping mapKeyPath:@"(sendungkey).desc" toAttribute:@"description"];
[mapping mapKeyPath:@"(sendungkey).duration" toAttribute:@"duration"];
[[RKObjectManager sharedManager].mappingProvider addObjectMapping:mapping ];
 mapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Sendung class] ];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:url objectMapping:mapping delegate:self];

这是我在 NSlogin 结果时得到的: ( (null), (null), (null), (null), (null) )

4

1 回答 1

5

我相信您错过了映射的一个“级别”。如果您仔细查看您的输入,您有一个字典 (key1),其中的内容不是单个 ' Sendung',而是一个此类对象的数组。因此,您不能将 key1 的内容直接映射到Sendungivars,而是创建新类,例如SendungResult.

@interface SendungResult : NSObject
    @property (nonatomic, strong) NSString *keyName;
    @property (nonatomic, strong) NSArray *sendungs;
@end

SendungResult sendungs并使用您现在直接使用的关系映射将key1 的内容映射到数组。

编辑:我将答案扩展如下:

正如我之前所说,您正在尝试将对象集合映射到单个实例中,因此这是行不通的。相反,您必须创建一个为一个键SendungResult保存一组Sendung实例的数组。因此,在您的示例中,您最终将得到两个SendungResult实例(一个将包含三个Sendungs - 嵌套在下面的那些"key1",第二个只有两个,嵌套在下面"key2")。您不能将这种结构映射到一个类中,您必须以与嵌套 JSON 相同的方式嵌套它们。类Sendung基本不变。

现在进行映射。您需要定义两个映射,一个会将根 JSON 的内容映射到两个SendungResult(每个键一个),第二个映射会将内部部分映射到各个Sendung实例。

我们从内部映射开始。

RKObjectMapping *sendungMapping = [RKObjectMapping mappingForClass:[Sendung class]];
[sendungMapping mapKeyPath:@"desc" toAttribute:@"desc"];
[sendungMapping mapKeyPath:@"duration" toAttribute:@"duration"];
[[[RKObjectManager sharedManager] mappingProvider] addObjectMapping:sendungMapping];

这里没有什么真正有趣的,我们只是将键路径映射到您的属性。现在是外部部分。

RKObjectMapping *resultMapping = [RKObjectMapping mappingForClass:[SendungResult class]];
[resultMapping setForceCollectionMapping:YES];
[resultMapping mapKeyOfNestedDictionaryToAttribute:@"keyName"];
[resultMapping mapKeyPath:@"(keyName)" toRelationship:@"sendungs" withMapping:sendungMapping];
[[[RKObjectManager sharedManager] mappingProvider] addObjectMapping:resultMapping];

我们告诉 RestKit 将 keyName keyPath 的内容映射到使用之前定义的映射在类上sendungs找到的属性。SendungResult

现在我们可以获取数据了

[[RKObjectManager sharedManager]  loadObjectsAtResourcePath:@"test.js" objectMapping:resultMapping delegate:self];

RestKit 将创建两个SendungResult实例,每个数组包含内部Sendung类(分别为 3 和 2)

注意:我强烈建议您阅读RestKit 对象映射文档。此外,JSONLint 发现您的 JSON 无效,我不得不删除分号。所以一定要使用有效的json。

于 2011-11-17T15:32:44.997 回答