2009-03-28 10 views
6

Piszę natywną aplikację na iPhone'a, korzystając ze środowiska JSON.Jak analizować zagnieżdżone obiekty JSON za pomocą frameworku JSON i Objective-C/iPhone/Xcode?

Moja aplikacja uzyskuje dostęp do usług WWW przy użyciu JSON. Dane JSON wysyłamy ma zagnieżdżone obiekty, poniżej jest przykładem danych serwowane:

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

Mam Problem parsowania przy użyciu metod objectForKey i valueForKey NSDictionary. Wciąż otrzymuję błędy środowiska wykonawczego invalidArgumentException.

Na przykład chcę zapytać o dane odpowiedzi dla elementu "authenticationFlag".

Dzięki, Mike Seattle

Odpowiedz

11

Trudno powiedzieć bez jakichś bardziej szczegółowych informacji (np kod analizowania JSON, że używasz), ale dwie rzeczy wydaje mi się to możliwe:

  1. nie pytasz o pełną ścieżkę. W powyższym przypadku, trzeba by najpierw uzyskać model otaczającą odpowiedź json, a dopiero potem prosić słownika odpowiedzi json dla wartości authenticationFlag:

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

  2. może używasz c- ciągi znaków ("") zamiast NSStrings (@"") jako klucze (chociaż może to spowodować awarię lub po prostu nie skompilować). Klucz powinien być czymś, co można odrzucić na id.

O ile to możliwe, obie są prawdopodobnie fałszywe, więc proszę podać więcej szczegółów.

+0

Rozwiązanie 1 działało. Zasadniczo musiałem przejść do węzła JSONRESPONSE, a następnie uzyskać dostęp do żądanego elementu. Dzięki! – 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

Poniżej jest pobierana bezpośrednio z Dan Grigsby tutorialu na - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - Proszę atrybutów, kradzież jest zła karma.

Pobieranie JSON przez HTTP

Użyjemy Cocoa NSURLConnection wydać żądanie HTTP i pobierać dane JSON.

Kakao zapewnia opcje synchroniczne i asynchroniczne do wysyłania żądań HTTP. Żądania synchroniczne uruchamiane z głównego runloopa aplikacji powodują zatrzymanie aplikacji podczas oczekiwania na odpowiedź. Prośby asynchroniczne używają wywołań zwrotnych, aby uniknąć blokowania i są proste w użyciu. Będziemy używać asynchronicznych żądań.

Pierwszą rzeczą, którą musimy zrobić, to zaktualizować interfejs kontrolera widoku, aby zawierał NSMutableData do przechowywania danych odpowiedzi. Deklarujemy to w interfejsie (a nie w metodzie), ponieważ odpowiedź powraca szeregowo w kawałkach, które łączymy, a nie w kompletnej jednostce.

#import <UIKit/UIKit.h> 

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

Aby wszystko było proste, uruchomimy żądanie HTTP z viewDidLoad.

Wymień zawartość:

#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 

To głównie boilerplate kod inicjuje zmienną responseData być gotowy do przechowywania danych i rozpoczyna połączenie w viewDidLoad; gromadzi kawałki, jak wchodzą w didReceiveData; a puste connectionDidFinishLoading jest gotowe do zrobienia czegoś z wynikami. Korzystanie z JSON Data

Następnie opracujemy metodę connectionDidFinishLoading, aby skorzystać z danych JSON pobranych w ostatnim kroku.

Aktualizacja metoda 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; 
} 

Tworzy NSArray. Parser jest bardzo elastyczny i zwraca obiekty - w tym obiekty zagnieżdżone - które odpowiednio pasują do typów danych JSON do typów danych Objective-C. Lepsza obsługa błędów

Do tej pory używaliśmy wygodnych, wysokopoziomowych rozszerzeń do metody NSString parsowania JSON. Zrobiliśmy to z dobrego powodu: przydaje się proste wysłanie komunikatu JSONValue do łańcucha, aby uzyskać dostęp do przeanalizowanych wartości JSON.

Niestety, użycie tej metody utrudnia obsługę błędów. Jeśli parser JSON nie powiedzie się z jakiegokolwiek powodu, po prostu zwraca wartość zerową. Jeśli jednak zobaczysz dziennik konsoli, gdy to nastąpi, zobaczysz komunikaty opisujące dokładnie, co spowodowało, że parser zakończył się niepowodzeniem.

Byłoby miło móc przekazać te szczegóły błędu użytkownikowi. W tym celu przejdziemy do drugiej, zorientowanej obiektowo metody obsługiwanej przez pakiet JSON SDK.

Aktualizacja metoda connectionDidFinishLoading w:

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

Korzystając z tej metody daje nam wskaźnik do obiektu błędu parsera JSON bazowego, które możemy wykorzystać do bardziej użyteczną obsługi błędów.

Wniosek:

JSON SDK i kakao wbudowanego wsparcia dla marki HTTP dodając JSON serwisów internetowych do iPhone apps proste.

+0

Mam format json jak to, jak mogę użyć proszę mi pomóc. jsont ({ "id" "ntp-a1.nict.go.jp" "to": 1232963971,248, "St": 1344228610,961, "skok": 34, "next": 1341100800, " krok ": 1 }) –

Powiązane problemy