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.