【问题标题】:RestKit Arbitrary Keys Object MappingRestKit 任意键对象映射
【发布时间】:2011-12-31 07:39:29
【问题描述】:

我有一个如下所示的 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 结果时得到的:( (空值), (空值), (空值), (空值), (空值) )

【问题讨论】:

  • 是的,因为你的 key1 的内容是一个数组。您能否发布您的实体以及映射定义?
  • 我编辑了这个问题。谢谢!我试图用 NSDictionary 来做,但由于我不知道键,这让我很困惑(
  • 不能使用描述作为属性。

标签: objective-c mapping restkit object-object-mapping


【解决方案1】:

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

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

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

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

正如我之前所说,您正在尝试将对象集合映射到单个实例中,因此这是行不通的。相反,您必须创建一个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 的内容映射到在 SendungResult 类上找到的 sendungs 属性,并使用之前定义的映射。

现在我们可以获取数据了

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

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

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

【讨论】:

  • 我试过了。这是代码: NSString url = [[NSString alloc] initWithFormat:@"/sendungen"] ; RKObjectMapping mapping = [RKObjectMapping mappingForClass:[Sendung class]]; [映射mapKeyPathsToAttributes:@“desc”,@“description”,@“duration”,@“duration”,nil];
  • for(NSString key in keys){ RKObjectMapping generalMapping = [RKObjectMapping mappingForClass:[OIdClass class] ]; [generalMapping mapKeyPath:key toAttribute:@"senders"]; [generalMapping mapKeyPath:key toRelationship:key withMapping:mapping]; [[RKObjectManager sharedManager].mappingProvider setMapping:generalMapping forKeyPath:key]; } [[RKObjectManager sharedManager] loadObjectsAtResourcePath:url delegate:self ];如您所见,我必须遍历我的键然后建立每个关系:(结果没有错误,但我得到空对象:()
  • 我不太明白为什么你必须迭代你的键。请参考我的另一个答案 - stackoverflow.com/questions/7726437/… 注意:该答案涉及发布一个对象数组,但此处适用相同的步骤,您只是不需要发送 [mapping inverseMapping] 选择器。
  • 请原谅我对这一切的了解不多,但我对它很陌生。 [syncEntityMapping mapKeyPath:@"mySyncArray" toRelationship:@"mySyncArray" withMapping:mngObjMapping];我应该为 KeyPath 写什么?我认为这是来自 JSON 文档的关键。这就是我迭代它们的原因..我的假设错了吗?我只是想如果我可以将它映射到字典可能会更好?然后可以保存所有密钥。有办法吗?非常感谢或回答!非常感谢!
  • 像魅力一样工作!不敢相信我自己没有来这里..再次感谢您!
猜你喜欢
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
相关资源
最近更新 更多