In previous blog post I’ve explained how to create iOS friendly ASP .NET web service with JSON RPC so now we’re going to take it further by creating an iPhone app that will consume this web service. Since iOS natively does not support JSON, we’ll be using this nice JSON framework available on Google Code here. This framework provides NSObject categories which allow simple JSON parsing and and it’s really convenient to use with iOS SDK. Other than that, we’ll be using native iOS SDK APIs only to create HTTP connection and query our JSON RPC service. Calling this web service is done by creating NSURLRequest with HTTP POST method and passing method name, method parameters (arguments) and identificator. NSURLConnection uses this request and does the magic we need. Let’s see the code.
First, we need to create JSON string which we’re going to POST to our RPC service. We do this by simply creating a dictionary and breaking it down to JSON representation.
//RPC NSMutableDictionary* reqDict = [NSMutableDictionary dictionary]; [reqDict setObject:methodName forKey:@"method"]; [reqDict setObject:parameters forKey:@"params"]; [reqDict setObject:identificator forKey:@"id"]; //RPC JSON NSString* reqString = [NSString stringWithString:[reqDict JSONRepresentation]]; |
We should note 3 arguments we’re posting to the service – method, params and id. Method is RPC method name as declared in JSON RPC web service. Params are arguments this method requires and ‘id’ is the call identifier which RPC call returns when sending back response and it’s used to link the response to the request in case you’re sending out multiple requests. In our case, the method name is ‘HelloWorld’ without arguments and as the identifier we’ll just put 1.
So now we create NSURLRequest and NSURLConnection using this reqString. This is the main part of code so pay attention.
//Request NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; NSData* requestData = [NSData dataWithBytes:[reqString UTF8String] length:[reqString length]]; //prepare http body [request setHTTPMethod: @"POST"]; [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody: requestData]; |
First we create a mutable url request, set it’s HTTP method to “POST” and fill out other HTTP specific header fields. Finally we set our JSON request string as HTTP body.
Now we simply create NSURLConnection, assign a delegate to it and wait for our data.
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; [request release]; |
The delegate part of the calling object has these methods defined.
#pragma mark - #pragma mark NSURLConnection delegate - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"Did receive response: %@", response); [webData release]; webData = [[NSMutableData alloc] init]; } -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { assert(webData != nil); [webData appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [webData release]; webData = nil; [urlConnection release]; urlConnection = nil; UIApplication* app = [UIApplication sharedApplication]; app.networkActivityIndicatorVisible = NO; //notify [delegate loadingFailed:[error localizedDescription]]; } -(void)connectionDidFinishLoading:(NSURLConnection *)connection { [urlConnection release]; urlConnection = nil; UIApplication* app = [UIApplication sharedApplication]; app.networkActivityIndicatorVisible = NO; //DO something with webData [delegate dataLoaded:webData]; [webData release]; webData = nil; } |
Once the connection gets a response we create NSData (webData) and we append bytes to it in didReceiveData callback. In the end we either get didFailWithError or didFinishLoading and take actions accordingly.
Finally, the app would return something like this when launched.
For your convenience, I have attached XCode project for download. Please note that this is an example only and should be treated as such, I don’t provide guarantee of any kind for this code.



