Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send json data in the Http request using NSURLRequest

I'm new to objective-c and I'm starting to put a great deal of effort into request/response as of recent. I have a working example that can call a url (via http GET) and parse the json returned.

The working example of this is below

- (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 {   NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); }  - (void)connectionDidFinishLoading:(NSURLConnection *)connection {     [connection release];   //do something with the json that comes back ... (the fun part) }  - (void)viewDidLoad {   [self searchForStuff:@"iPhone"]; }  -(void)searchForStuff:(NSString *)text {   responseData = [[NSMutableData data] retain];     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.whatever.com/json"]];     [[NSURLConnection alloc] initWithRequest:request delegate:self]; } 

My first question is - will this approach scale up? Or is this not async (meaning I block the UI thread while the app is waiting for the response)

My second question is - how might I modify the request part of this to do a POST instead of GET? Is it simply to modify the HttpMethod like so?

[request setHTTPMethod:@"POST"]; 

And finally - how do I add a set of json data to this post as a simple string (for example)

{     "magic":{                "real":true             },     "options":{                "happy":true,                 "joy":true,                 "joy2":true               },     "key":"123" } 

Thank you in advance

like image 925
Toran Billups Avatar asked Dec 16 '10 02:12

Toran Billups


People also ask

Can we send JSON via HTTP GET request?

To answer your question, yes you may pass JSON in the URI as part of a GET request (provided you URL-encode).

Can we send JSON object in post request?

To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.


2 Answers

Here's what I do (please note that the JSON going to my server needs to be a dictionary with one value (another dictionary) for key = question..i.e. {:question => { dictionary } } ):

NSArray *objects = [NSArray arrayWithObjects:[[NSUserDefaults standardUserDefaults]valueForKey:@"StoreNickName"],   [[UIDevice currentDevice] uniqueIdentifier], [dict objectForKey:@"user_question"],     nil]; NSArray *keys = [NSArray arrayWithObjects:@"nick_name", @"UDID", @"user_question", nil]; NSDictionary *questionDict = [NSDictionary dictionaryWithObjects:objects forKeys:keys];  NSDictionary *jsonDict = [NSDictionary dictionaryWithObject:questionDict forKey:@"question"];  NSString *jsonRequest = [jsonDict JSONRepresentation];  NSLog(@"jsonRequest is %@", jsonRequest);  NSURL *url = [NSURL URLWithString:@"https://xxxxxxx.com/questions"];  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url              cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];   NSData *requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];  [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData];  NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; if (connection) {  receivedData = [[NSMutableData data] retain]; } 

The receivedData is then handled by:

NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSDictionary *jsonDict = [jsonString JSONValue]; NSDictionary *question = [jsonDict objectForKey:@"question"]; 

This isn't 100% clear and will take some re-reading, but everything should be here to get you started. And from what I can tell, this is asynchronous. My UI is not locked up while these calls are made. Hope that helps.

like image 200
Mike G Avatar answered Sep 22 '22 17:09

Mike G


I struggled with this for a while. Running PHP on the server. This code will post a json and get the json reply from the server

NSURL *url = [NSURL URLWithString:@"http://example.co/index.php"]; NSMutableURLRequest *rq = [NSMutableURLRequest requestWithURL:url]; [rq setHTTPMethod:@"POST"]; NSString *post = [NSString stringWithFormat:@"command1=c1&command2=c2"]; NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding]; [rq setHTTPBody:postData]; [rq setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; NSOperationQueue *queue = [[NSOperationQueue alloc] init];  [NSURLConnection sendAsynchronousRequest:rq queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)  {      if ([data length] > 0 && error == nil){          NSError *parseError = nil;          NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];          NSLog(@"Server Response (we want to see a 200 return code) %@",response);          NSLog(@"dictionary %@",dictionary);      }      else if ([data length] == 0 && error == nil){          NSLog(@"no data returned");          //no data, but tried      }      else if (error != nil)      {          NSLog(@"there was a download error");          //couldn't download       }  }]; 
like image 34
user3344717 Avatar answered Sep 20 '22 17:09

user3344717