Как проанализировать вложенные объекты JSON с помощью инфраструктуры JSON и Objective-C / iPhone / Xcode? - PullRequest
6 голосов
/ 28 марта 2009

Я пишу нативное приложение для iPhone с использованием фреймворка JSON.

Мое приложение обращается к веб-службам с помощью JSON. Данные JSON, которые мы отправляем, содержат вложенные объекты, ниже приведен пример обработки данных:

{
    "model": {
        "JSONRESPONSE": {
            "authenticationFlag": true,
            "sessionId": "3C4AA754D77BFBE33E0D66EBE306B8CA",
            "statusMessage": "Successful Login.",
            "locId": 1,
            "userName": "Joe Schmoe"
        }
    }
}

У меня проблема с анализом с использованием методов NSDictionary objectForKey и valueForKey. Я продолжаю получать недопустимые ошибки времени исполнения invalidArgumentException.

Например, я хочу запросить данные ответа для элемента «authenticationFlag».

Спасибо, Майк Сиэтл

Ответы [ 4 ]

11 голосов
/ 29 марта 2009

Трудно сказать без каких-либо дополнительных подробностей (например, код разбора JSON, который вы используете), но две вещи поражают меня, насколько это возможно:

  1. вы не запрашиваете полный путь. В приведенном выше случае вам сначала нужно получить включающую модель, ответ json, и только потом запрашивать в словаре ответов json значение authenticationFlag:

    [[[jsonDict objectForKey:@"model"] objectForKey:@"JSONRESPONSE"] objectForKey:@"authenticationFlag"]

  2. возможно, вы используете c-строки (""), а не NSStrings (@"") в качестве ключей (хотя это, скорее всего, приведет к сбою или просто не скомпилируется). Ключ должен быть чем-то, что можно привести к id.

Хотя это возможно, оба, вероятно, неверны, поэтому, пожалуйста, включите более подробную информацию.

2 голосов
/ 02 марта 2011

Следующее взято непосредственно из Учебника Дэна Григсби по адресу - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - Пожалуйста, объясните, воровство - это плохая карма.

Загрузка JSON через HTTP

Мы будем использовать NSURLConnection от Cocoa для выдачи HTTP-запроса и получения данных JSON.

Какао предоставляет как синхронные, так и асинхронные опции для выполнения HTTP-запросов. Синхронные запросы, запускаемые из основного цикла запуска приложения, приводят к остановке приложения в ожидании ответа. Асинхронные запросы используют обратные вызовы, чтобы избежать блокировки, и просты в использовании. Мы будем использовать асинхронные запросы.

Первое, что нам нужно сделать, это обновить интерфейс нашего контроллера представления, добавив в него NSMutableData для хранения данных ответа. Мы объявляем это в интерфейсе (а не внутри метода), потому что ответ возвращается последовательно по частям, которые мы сшиваем вместе, а не по целому блоку.

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    IBOutlet UILabel *label;
    NSMutableData *responseData;
}

Для простоты мы запустим HTTP-запрос от viewDidLoad.

Заменить содержимое:

#import "JSON/JSON.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    responseData = [[NSMutableData data] retain];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"XYZ.json"]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
}

- (void)dealloc {
    [super dealloc];
}

@end

Этот в основном шаблонный код инициализирует переменную responseData, чтобы быть готовой к хранению данных, и запускает соединение в viewDidload; он собирает части по мере их поступления в didReceiveData; и пустое connectionDidFinishLoading готово что-то сделать с результатами. Использование данных JSON

Далее мы уточним метод connectionDidFinishLoading, чтобы использовать данные JSON, полученные на последнем шаге.

Обновить метод connectionDidFinishLoading:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

    NSArray *luckyNumbers = [responseString JSONValue];

    NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];

    for (int i = 0; i < [luckyNumbers count]; i++)
        [text appendFormat:@"%@\n", [luckyNumbers objectAtIndex:i]];

    label.text =  text;
}

Создает NSArray. Синтаксический анализатор очень гибок и возвращает объекты - включая вложенные объекты - которые надлежащим образом соответствуют типам данных JSON и типам данных Objective-C. Лучшая обработка ошибок

До настоящего времени мы использовали удобные высокоуровневые расширения метода NSString для анализа JSON. Мы сделали это по уважительной причине: удобно просто отправить сообщение JSONValue в строку для доступа к проанализированным значениям JSON.

К сожалению, использование этого метода усложняет обработку ошибок. Если анализатор JSON по какой-либо причине дает сбой, он просто возвращает нулевое значение. Однако, если вы посмотрите журнал консоли, когда это произойдет, вы увидите сообщения, в которых точно описывается причина сбоя синтаксического анализатора.

Было бы хорошо иметь возможность передавать эти подробности об ошибках пользователю. Для этого мы переключимся на второй объектно-ориентированный метод, который поддерживает JSON SDK.

Обновите метод connectionDidFinishLoading в:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

    NSError *error;
    SBJSON *json = [[SBJSON new] autorelease];
    NSArray *luckyNumbers = [json objectWithString:responseString error:&error];
    [responseString release];   

    if (luckyNumbers == nil)
        label.text = [NSString stringWithFormat:@"JSON parsing failed: %@", [error localizedDescription]];
    else {
        NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];

        for (int i = 0; i < [luckyNumbers count]; i++)
            [text appendFormat:@"%@\n", [viewcontroller objectAtIndex:i]];

        label.text =  text;
    }
}

Использование этого метода дает нам указатель на объект ошибки базового анализатора JSON, который мы можем использовать для более полезной обработки ошибок.

Вывод:

JSON SDK и встроенная поддержка HTTP для Cocoa упрощают добавление веб-служб JSON в приложения для iPhone.

1 голос
/ 09 февраля 2011
    NSString* aStr;
    aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSDictionary *dictionary = [aStr JSONValue];
    NSArray *keys = [dictionary allKeys];

    // values in foreach loop
    for (NSString *key in keys) {
    NSArray *items = (NSArray *) [dictionary objectForKey:key];  

        for (id *item in items) {  


            NSString* aStrs=  item;
            NSLog(@" test %@", aStrs);

            NSDictionary *dict = aStrs;
            NSArray *k = [dict allKeys];

        for (id *it in k) {  
                            NSLog(@"the  child item: %@", [NSString stringWithFormat:@"Child Item -> %@ value %@", (NSDictionary *) it,[dict objectForKey:it]]);                
                        }
0 голосов
/ 27 июля 2012

Теперь Objective c введен в класс сборки для анализа JSON.

 NSError *myError = nil;
 NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:&myError];

http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html

Так что используйте этот класс и сделайте ваше приложение без ошибок ...:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...