Friday, January 20, 2012

Retrieve JSON from Web service and Decode JSON String with SBJSON

Now that I showed how to encode something to JSON string using SBJson in the post Convert NSDictionary to JSON I would like to show you how to retrieve and decode an JSON String coming from a Web Service.

You will need the JSON-Framework (https://github.com/stig/json-framework) for this example.

I won't hold a long talk and just go straight down to the code.

#import "myController.h"
#import "SBJSON.h"


@implementation myController

- (id) httpPostJson:(NSString*) JsonString toURL:(NSURL*) serverURL {
    NSData* postData = [JsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    NSString* postLength = [NSString stringWithFormat:@"%d", [postData length]];
    NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];

    [request setURL:serverURL];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSData *returnData      = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];

    SBJsonParser* jsonParser = [SBJsonParser new];

    return [jsonParser objectWithString:[[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding] error:NULL];   

}


We just assume that our imaginary web service is communicating with us in JSON only.
Therefore I created a simple function which we just have to feed with a JSON string containing a Dictionary or Array and the actual URL of the web service.

The Breakdown

- (id) httpPostJson:(NSString*) JsonString toURL:(NSURL*) serverURL

And Yes, for this example I live in a perfect world and do not care about any secure connection ;-)

First thing we do is do create an NSData object that we can use together with NSURLConnection:
NSData* postData = [JsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

Than we have to figure out how much data we are actually sending to the server
NSString* postLength = [NSString stringWithFormat:@"%d", [postData length]];

and we have to create an NSMutableRequest object

NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];

Good, now we are almost done.
Next we have to set all Header information .
First we set the Server URL

[request setURL:serverURL];

the Request method is next with

[request setHTTPMethod:@"POST"];

the request size

[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

and, actually important, the Content Type

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

Please do not forget the Content Type as Programming Frameworks such as Pylons (as an example) can give you a hard time if you do not set the Content Type.

And last but not least we have to set our message body

[request setHTTPBody:postData];

Okay, now we just initialise the JSON Parser with

SBJsonParser* jsonParser = [SBJsonParser new];

and convert our result that will come as NSData to NSString and use the JSON Parser to return the appropriate ObjectiveC object

[jsonParser objectWithString:[[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding] error:NULL]; 

In our example I return it as an ID object but you can use whatever is suitable for your situation.
If you know that the service you are connecting to is always returning an NSDictionary replace ID with an NSDictionary etc.
As mentioned in the beginning of this post, I do not care about security and error handling in this post.
I will address SSL connections and how to handle errors in a later post.

And please feel free to leave any comments be it a question, critic, a wish or anything else I can currently not think of.

So long. Happy coding days.

2 comments:

  1. if i make a request to php server for login users so how i can get the loggen in user details.


    ReplyDelete
  2. how can i save a server user id and use in ios app.

    ReplyDelete