在 Objective C 中使用 RestKit 解析复杂的 JSON
Posted
技术标签:
【中文标题】在 Objective C 中使用 RestKit 解析复杂的 JSON【英文标题】:Parsing complex JSON using RestKit in Objective C 【发布时间】:2012-01-28 09:00:36 【问题描述】:我已经为此问题困扰了几天,如果有人能够为此提供一些指导甚至完整的代码解决方案,我将不胜感激。 我正在尝试使用 RestKit 将动态对象映射到 Objective C 中的 JSON 字符串,但似乎无法获得正确的值。 这是我需要解析的那种 JSON 响应的示例:
"Boy" :
"favoriteClass" : "math",
"basicInfo" :
"name" : "John",
"age" : 10,
"type" : 1
"friends" :
[
"Boy" :
"favoriteClass" : "PE"
"basicInfo" :
"name" : "Bill",
"age" : 12,
"type" : 1
"friends" : []
,
"Girl" :
"favoriteTeacher" : "Mrs. Manson"
"basicInfo" :
"name" : "Sara",
"age" : 11,
"type" : 2
"friends" : []
,
"Girl" :
"favoriteTeacher" : "Mr. Chase"
"basicInfo" :
"name" : "Ronda",
"age" : 9,
"type" : 2
"friends" : []
]
意思是,我有两种类型的类:购买类和女孩类。 它们每个都有不同的字段(男孩的 favoriteClass 和女孩的 favouriteTeacher),但两者都有一个 basicInfo 字段,其中包含完全相同的结构。 我可以通过使用数组中记录的名称(“Boy”或“Girl”)或通过“type”字段中的值来判断哪些应该映射到 Boy 类,哪些应该映射到 Girl 类“basicInfo”记录(男孩 1 个,女孩 2 个)。 Boy 和 Girl 类的friends 数组可以包含男孩和女孩的实例。
谁能给我一些关于如何做到这一点的指示? 任何帮助将不胜感激。
谢谢,
【问题讨论】:
【参考方案1】:我今天才开始研究 RestKit,所以我远离权威。但是,查看 Blake 的优秀文档,在我看来您过于复杂了(您发布的 JSON 不验证 BTW)。除非您特别需要 BasicInfo
对象,否则我会删除它并配置您的 JSON:
"people": [
"age": 10,
"favoriteClass": "math",
"name": "John",
"type": 1,
"friends": [
"age": 12,
"favoriteClass": "PE",
"friends": [],
"name": "Bill",
"type": 1
,
"age": 11,
"favoriteTeacher": "Mrs. Manson",
"friends": [],
"name": "Sara",
"type": 2
,
"age": 9,
"favoriteTeacher": "Mr. Chase",
"friends": [],
"name": "Ronda",
"type": 2
]
]
那么您应该能够利用他在Object Mapping document. 的 动态对象映射 部分中描述的方法 (1) 在我看来,与示例相比,您唯一的区别他给出的是,您在每个 Boy
和 Girl
类中都有一些额外的 ivars,并且您使用数字而不是字符串来识别 Boy
和 Girl
。你可以通过修改他给出的声明来解决这个问题:
// Basic setup
RKObjectMapping* boyMapping = [RKObjectMapping mappingForClass:[Boy class]];
[boyMapping mapAttributes:@"age", @"name", @"favoriteClass",nil];
RKObjectMapping* girlMapping = [RKObjectMapping mappingForClass:[Girl class]];
[girlMapping mapAttributes:@"age", @"name", @"favoriteTeacher", nil];
// Configure the dynamic mapping via matchers
[dynamicMapping setObjectMapping:boyMapping whenValueOfKeyPath:@"type" isEqualTo:@"1"];
[dynamicMapping setObjectMapping:girlMapping whenValueOfKeyPath:@"type" isEqualTo:@"2"];
匹配器的类型可能不太对——正如我所说,我今天才开始阅读这些东西。
【讨论】:
【参考方案2】:只需以有纪律的方式遍历层次结构即可。
//pseudo code
for (id child in JSONObject)
if (it is a boy) create new boy object;
else create new girl object;
fill in the info;
for (id child in friends)
if (it is a boy) create new boy object;
else create new girl object;
fill in the info;
当然,整个数据方案是可笑的重复。在我看来,你应该只有一个类 Child 无论如何都有一个属性 basicInfo.type
来标识它是男孩还是女孩,所以不需要额外的类。
此外,如果您有一个相互为朋友的孩子的列表,您最终会多次列出许多孩子。更好的是在朋友字段中有一个具有唯一 ID 的简单数组。
【讨论】:
感谢您的快速回复,但我对如何使用 RestKit API 执行此操作很感兴趣。如果您有任何使用它的经验,如果您可以在此处发布一些其他信息,那就太好了。谢谢...【参考方案3】:您只需要使用像 SBJSON 这样的 JSON 解析器,SBJSON 可以像这样解析您收到的数据:
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *received = [parser objectWithData:data];
但是,如果你想使用 Restkit,它也有一个内置的解析器。我相信它会像这样工作:
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
RKJSONParser* parser = [RKJSONParser new];
NSDictionary *dict = [parser objectFromString:[response bodyAsString]];
希望对你有帮助。
【讨论】:
以上是关于在 Objective C 中使用 RestKit 解析复杂的 JSON的主要内容,如果未能解决你的问题,请参考以下文章
Restkit + Objective-c - 多次调用同一个 Web 服务