【问题标题】:Parsing complex JSON using RestKit in Objective C在 Objective C 中使用 RestKit 解析复杂的 JSON
【发布时间】: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 数组可以包含男孩和女孩的实例。

谁能给我一些关于如何做到这一点的指示? 任何帮助将不胜感激。

谢谢,

【问题讨论】:

    标签: objective-c json parsing rest restkit


    【解决方案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]]; 
      }
      

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 2013-06-12
        • 1970-01-01
        • 2013-06-06
        • 2016-04-21
        相关资源
        最近更新 更多