How to parse nested JSON objects using JSON structure and Objective-C / iPhone / Xcode?

I am writing a native iPhone application using the JSON framework.

My application has access to web services using JSON. The JSON data we send has nested objects, the following is an example of data:

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

I am having a problem with parsing using objectForKey and valueForKey NSDictionary methods. I keep getting invalidArgumentException errors.

For example, I want to request response data for an authenticationFlag element.

Thanks Mike Seattle

+6
json objective-c iphone xcode
Mar 28 '09 at 5:09
source share
4 answers

It's hard to say without any details (like the JSON parsing code you use), but two things hit me:

  • You are not requesting the full path. In the above case, you need to first get the attached model, the json response, and only then ask the json response dictionary for the authenticationFlag value:

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

  • perhaps you are using c-strings ( "" ) rather than NSStrings ( @"" ) as keys (although this is most likely to happen with an error or just won't compile). The key must be something other than id.

Although it’s possible, both of them are probably false, so please provide more details.

+11
Mar 29 '09 at 2:45
source share

The following is taken from Dan Grigsby’s tutorial at http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - Please attribute, theft is bad karma.

Getting JSON over HTTP

It is good to use Cocoa s NSURLConnection to request an HTTP request and receive JSON data.

Cocoa provides both synchronous and asynchronous parameters for HTTP requests. Synchronous requests launched from the main application environment cause the application to stop while it waits for a response. Asynchronous requests use callbacks to avoid blocking and are easy to use. It is good to use asynchronous requests.

First of all, we need to update the interface of our view controllers to enable NSMutableData to store response data. We declare this in the interface (and not inside the method), because the response is returned sequentially in parts that we sew together, and not in a complete block.

 #import <UIKit/UIKit.h> @interface ViewController : UIViewController { IBOutlet UILabel *label; NSMutableData *responseData; } 

To keep things simple, open your HTTP request from viewDidLoad well.

Replace the contents:

 #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 

This main template code initializes the responseData variable to be ready to store data and starts the connection in viewDidload; it collects parts when they enter didReceiveData; and an empty connectionDidFinishLoading is ready to do something with the results. Using JSON Data

Next, fine tune the connectionDidFinishLoading method to use the JSON data received in the last step.

Update connectionDidFinishLoading method:

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

It creates an NSArray. The parser is very flexible and returns objects, including nested objects, which respectively correspond to JSON data types for Objective-C data types. Improved error handling

So far, we have used convenient high-level extensions for the NSString method to parse JSON. Weve did this for a good reason: it's convenient to just send a JSONValue message to a string to access collapsible JSON values.

Unfortunately, using this method makes error handling difficult. If the JSON parser does not work for any reason, it simply returns nil. However, if you keep track of your console log when this happens, you will see messages describing what caused the parser to fail.

Itd be nice to be able to share this error information with the user. To do this, switch well to the second object-oriented method supported by the JSON SDK.

Update the connectionDidFinishLoading method to:

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

Using this method gives us a pointer to the error object of the basic JSON analyzer, which we can use for more useful error handling.

Conclusion:

JSON SDK and Cocoa support for native HTTP support makes it easy to add JSON web services to iPhone applications.

+2
Mar 02 2018-11-11T00:
source share
  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]]); } 
+1
Feb 09 '11 at 18:49
source share

Objective-c is now introduced in the assembly class for JSON Parsing.

  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

So use this class and free the application from errors ... :)

0
Jul 27 2018-12-12T00:
source share



All Articles