Синтаксический анализ JSON с использованием RestKit в Objective C - PullRequest
2 голосов
/ 28 января 2012

У меня были проблемы с этой проблемой в течение нескольких дней, и я был бы очень признателен, если бы кто-то смог предоставить какое-то руководство или даже полное кодовое решение для этого. Я пытаюсь выполнить динамическое сопоставление объектов со строкой JSON в Objective C с помощью RestKit и не могу получить правильные значения. Вот пример ответа 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 с использованием имени записи в массиве («Boy» или «Girl») или по значению поля «type» в пределах запись "basicInfo" (1 для мальчиков и 2 для девочек). Массив друзей для классов Boy и Girl может содержать экземпляры как мальчиков, так и девочек.

Кто-нибудь может дать мне несколько советов, как это можно сделать? Любая помощь будет принята с благодарностью.

Спасибо

Ответы [ 3 ]

2 голосов
/ 10 февраля 2012

Я только начал смотреть на RestKit сегодня, поэтому я далеко от авторитета. Однако, глядя на отличную документацию Блейка, мне кажется, что вы слишком усложняете это (ваш опубликованный 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
                }
            ] 
        }
    ]
}

Тогда вы сможете использовать подход (1), который он описывает в разделе Динамическое сопоставление объектов документа Сопоставление объектов. Мне кажется, единственное отличие, которое вы По сравнению с примером, который он приводит, у вас есть несколько дополнительных иваров в каждом из классов Boy и Girl, и вы используете число вместо строки для идентификации 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"];

Тип совпадения может быть не совсем правильным - как я уже сказал, я только сегодня начал читать этот материал.

0 голосов
/ 29 января 2012

Вам просто нужно использовать JSON-анализатор, такой как SBJSON, 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]]; 
}

Надеюсь, это поможет вам.

0 голосов
/ 28 января 2012

Просто пройдите иерархию дисциплинированным образом.

//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, который идентифицирует его как мальчика или девочку, поэтому не нужно иметь дополнительный класс.

Кроме того, если у вас есть список друзей, которые дружат друг с другом, вы в конечном итоге перечислите много детей несколько раз.Гораздо лучше было бы иметь простой массив с уникальными идентификаторами в поле друзей.

...