2009-03-28 11 views
6

Estoy escribiendo una aplicación nativa para iPhone usando el framework JSON.Cómo analizar objetos JSON anidados con el marco JSON y Objective-C/iPhone/Xcode?

Mi aplicación está accediendo a los servicios web utilizando JSON. Los datos JSON enviamos ha anidado objetos, a continuación es un ejemplo de los datos servidos:

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

estoy teniendo problema al analizar el uso de los métodos y objectForKey valueForKey NSDictionary. Sigo recibiendo errores de tiempo de ejecuciónArgumentException no válidos.

Por ejemplo, deseo consultar los datos de respuesta para el elemento "authenticationFlag".

Gracias, Mike Seattle

Respuesta

11

Es difícil de decir sin algunos detalles más (por ejemplo, el código de análisis JSON que está utilizando), pero dos cosas me parecen posibles:

  1. no estás consultando con un camino completo. En el caso anterior, que había necesidad de obtener primero el modelo de cerramiento, la respuesta JSON, y sólo entonces pide el diccionario respuesta JSON para el valor authenticationFlag:

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

  2. quizás usted está utilizando c- strings ("") en lugar de NSStrings (@"") como claves (aunque es probable que se cuelguen desagradablemente o simplemente no se compilen). La clave debe ser algo que no se puede convertir a la identificación.

Si bien es posible, ambos son probablemente falsos, por favor incluya más detalles.

+0

Solución 1 funcionó. Esencialmente, necesitaba atravesar el nodo JSONRESPONSE para poder acceder al elemento deseado. ¡Gracias! – mibrop

1
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]]);     
         } 
2

Lo siguiente fue tomado directamente del Tutorial de Dan Grigsby en - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - Por favor, atribuir, robar es un mal karma.

Fetching JSON a través de HTTP

Usaremos NSURLConnection de cacao para emitir una solicitud HTTP y recuperar los datos JSON.

Cocoa proporciona opciones síncronas y asíncronas para realizar solicitudes HTTP. Las solicitudes sincrónicas que se ejecutan desde el runloop principal de la aplicación hacen que la aplicación se detenga mientras espera una respuesta. Las solicitudes asincrónicas utilizan devoluciones de llamada para evitar el bloqueo y son fáciles de usar. Usaremos solicitudes asincrónicas.

Lo primero que debemos hacer es actualizar la interfaz de nuestra controladora de vistas para incluir un NSMutableData que contenga los datos de respuesta. Declaramos esto en la interfaz (y no dentro de un método) porque la respuesta regresa en serie en piezas que unimos en lugar de en una unidad completa.

#import <UIKit/UIKit.h> 

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

Para simplificar, iniciaremos la solicitud HTTP de viewDidLoad.

sustituir el contenido de:

#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 

Este código principalmente repetitivo inicializa la variable ResponseData para estar listo para contener los datos y se inicia la conexión en viewDidLoad; reúne las piezas a medida que entran en didReceiveData; y la conexión vacíaDidFinishLoading está lista para hacer algo con los resultados. Usando los datos JSON

A continuación, desarrollaremos el método connectionDidFinishLoading para hacer uso de los datos JSON recuperados en el último paso.

el método de actualización de 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; 
} 

Se crea una NSArray. El analizador sintáctico es muy flexible y devuelve objetos, incluidos objetos anidados, que combinan adecuadamente los tipos de datos JSON con los tipos de datos Objective-C. Mejor manejo de errores

Hasta ahora, hemos estado utilizando las convenientes extensiones de alto nivel del método NSString para analizar JSON. Lo hemos hecho con una buena razón: es útil simplemente enviar el mensaje JSONValue a una cadena para acceder a los valores JSON analizados.

Desafortunadamente, el uso de este método dificulta el manejo de errores. Si el analizador JSON falla por algún motivo, simplemente devuelve un valor nulo. Sin embargo, si ve el registro de su consola cuando esto sucede, verá mensajes que describen con precisión qué causó el error del analizador.

Sería bueno poder pasar los detalles del error junto con el usuario. Para hacerlo, cambiaremos al segundo método orientado a objetos compatible con JSON SDK.

el método de actualización en 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; 
    } 
} 

uso de este método nos da un puntero al objeto de error del analizador JSON subyacente que podemos utilizar para el tratamiento de errores más útil.

Conclusión:

El SDK JSON y Cacao de soporte incorporado para el maquillaje HTTP añadiendo servicios web JSON para iPhone Apps sencillo.

+0

Tengo un formato json como este, cómo puedo usar, por favor, ayúdenme. jsont ({ "id": "ntp-a1.nict.go.jp", "él": 1232963971.248, "st": 1,344,228,610.961, "salto": 34, "siguiente": 1341100800, " paso ": 1 }) –

Cuestiones relacionadas