在Objective C中使用RestKit解析复杂的JSON

时间:2012-01-28 09:00:37

标签: objective-c json parsing rest restkit

我已经在这个问题上遇到了好几天的问题,如果有人能够为此提供一些指导甚至完整的代码解决方案,我将非常感激。 我正在尝试使用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" : []
              }
           }
        ]
    }
}

意思是,我有两种类型:一个Buy类和一个Girl类。 他们每个人都有不同的领域(男孩们最喜欢的课程和女孩们最喜欢的教师),但两者都有一个basicInfo字段,它包含完全相同的结构。 我可以告诉哪些应该映射到Boy类,哪些应该映射到Girl类,使用数组中的记录名称(“男孩”或“女孩”),或者通过“类型”字段的值。 “basicInfo”记录(男孩1个,女孩2个)。 男孩和女孩的朋友阵列可以包含男孩和女孩的实例。

有人可以就如何做到这一点给我一些指示吗? 任何帮助将不胜感激。

谢谢,

3 个答案:

答案 0 :(得分:2)

我今天刚刚开始关注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,并且您使用数字而不是字符串来标识Boy vs {{1} }。你可以通过修改他给出的声明来解决这个问题:

Girl

匹配器的类型可能不太正确 - 正如我所说,我今天才开始阅读这些内容。

答案 1 :(得分:0)

以规范的方式完成层次结构。

//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,可以将它标识为男孩或女孩,所以不需要额外的课程。

此外,如果您有一个彼此是朋友的孩子列表,您最终会多次列出许多孩子。更好的方法是在friends字段中创建一个具有唯一ID的简单数组。

答案 2 :(得分:0)

您只需要使用像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]]; 
}

我希望能帮助你。