在 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) 在我看来,与示例相比,您唯一的区别他给出的是,您在每个 BoyGirl 类中都有一些额外的 ivars,并且您使用数字而不是字符串来识别 BoyGirl。你可以通过修改他给出的声明来解决这个问题:

// 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的主要内容,如果未能解决你的问题,请参考以下文章

Objective C + RESTKit:获取对象的问题

Restkit + Objective-c - 多次调用同一个 Web 服务

Objective-C RestKit 没有输出

RestKit:JSON 映射不起作用 Objective-c

如何在使用 RestKit 的项目中设计类?

将restkit安装到xcode中-总是这么复杂吗?