2009-03-28 16 views
6

Sto scrivendo un'app nativa per iPhone utilizzando il framework JSON.Come analizzare gli oggetti JSON nidificati con framework JSON e Objective-C/iPhone/Xcode?

La mia app accede ai servizi Web utilizzando JSON. I dati JSON inviamo ha nidificato oggetti, qui di seguito è un esempio dei dati servito:

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

sto avendo problemi di analisi utilizzando i metodi objectForKey e valueForKey NSDictionary. Continuo a ricevere errori di runtime non validi di ArgumentException.

Per esempio, voglio interrogare i dati di risposta per l'elemento "authenticationFlag".

Grazie, Mike Seattle

risposta

11

E 'difficile dire senza qualche dettaglio in più (ad esempio il codice di analisi JSON che si sta utilizzando), ma due cose mi colpiscono più possibile:

  1. non stai interrogando con un percorso completo. Nel caso di cui sopra, avresti bisogno di ottenere il primo modello che racchiude, la risposta JSON, e solo allora chiedere al dizionario risposta JSON per il valore authenticationFlag:

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

  2. forse si sta utilizzando c- stringhe ("") piuttosto che NSStrings (@"") come chiavi (anche se questo potrebbe bloccarsi rapidamente o semplicemente non essere compilato). La chiave dovrebbe essere qualcosa che può essere lanciato su id.

Sebbene sia possibile, entrambi sono probabilmente falsi, quindi per favore includere maggiori dettagli.

+0

Soluzione 1 ha funzionato. Essenzialmente, dovevo attraversare il nodo JSONRESPONSE, quindi ho potuto accedere all'elemento desiderato. Grazie! – 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

Il seguente è tratto direttamente dal Tutorial di Dan Grigsby a - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - attribuiscili, rubare è cattivo karma.

Recupero JSON su HTTP

Useremo NSURLConnection di cacao di emettere una richiesta HTTP e recuperare i dati JSON.

Cocoa fornisce sia le opzioni sincrone che quelle asincrone per effettuare richieste HTTP. Le richieste sincrone eseguite dal runloop principale dell'applicazione causano l'interruzione dell'applicazione mentre attende una risposta. Le richieste asincrone utilizzano le callback per evitare il blocco e sono semplici da utilizzare. Useremo richieste asincrone.

La prima cosa che dobbiamo fare è aggiornare l'interfaccia del nostro controller di visualizzazione per includere NSMutableData per contenere i dati di risposta. Lo dichiariamo nell'interfaccia (e non all'interno di un metodo) perché la risposta ritorna in serie in pezzi che ricuciamo insieme piuttosto che in un'unità completa.

#import <UIKit/UIKit.h> 

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

Per semplificare le cose, daremo il via alla richiesta HTTP da viewDidLoad.

sostituire il contenuto di:

#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 

Questo codice principalmente boilerplate inizializza la variabile responseData per essere pronti per contenere i dati e inizia la connessione in viewDidLoad; raccoglie i pezzi mentre entrano in didReceiveData; e la connessione vuotaDidFinishLoading è pronta a fare qualcosa con i risultati. Utilizzo di JSON Data

Successivamente, verrà illustrato il metodo connectionDidFinishLoading per utilizzare i dati JSON recuperati nell'ultimo passaggio.

Aggiornare il metodo 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; 
} 

Si crea un NSArray. Il parser è molto flessibile e restituisce oggetti, inclusi oggetti nidificati, che abbinano in modo appropriato i tipi di dati JSON ai tipi di dati Objective-C. Migliore gestione degli errori

Finora, abbiamo utilizzato le convenienti estensioni di alto livello del metodo NSString per l'analisi di JSON. Lo abbiamo fatto con una buona ragione: è utile inviare semplicemente il messaggio JSONValue a una stringa per accedere ai valori JSON analizzati.

Sfortunatamente, l'uso di questo metodo rende difficile la gestione degli errori. Se il parser JSON fallisce per qualsiasi motivo, restituisce semplicemente un valore nullo. Tuttavia, se guardi il log della tua console quando questo accade, vedrai messaggi che descrivono precisamente cosa ha causato il fallimento del parser.

Sarebbe bello poter passare questi dettagli di errore all'utente. Per fare ciò, passeremo al secondo metodo orientato agli oggetti supportato da JSON SDK.

Aggiornare il metodo connectionDidFinishLoading in:

- (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; 
    } 
} 

Utilizzando questo metodo ci dà un puntatore all'oggetto di errore del parser JSON sottostante che possiamo usare per la gestione degli errori più utile.

Conclusione:

L'SDK JSON e Cocoa di supporto integrato per il trucco HTTP l'aggiunta di servizi web JSON per iPhone apps semplice.

+0

Ho un formato JSON come questo, come posso usare per favore aiutami. jsont ({ "id": "ntp-a1.nict.go.jp", "it": 1232963971,248, "st": 1344228610,961, "salto": 34, "next": 1341,1008 milioni, " passo ": 1 }) –

Problemi correlati