How to send HTTP requests from iOS

Hey pals, today we talk about how to send HTTP GET and POST requests to a server from your iOS application. This post I am implementing server side also. Therefore we will use localhost as our server. Next speciality is, you will learn how to send custom HTTP headers in iOS in this tutorial. We are not going to use any kind of library such as AFNetworking, due to learning purpose.  

Today we are not going to consider about the user interfaces. For simplicity of the post, I’m writing all the stuff inside my ViewController class. But you  can separate those in to your Modal class in your project.

HTTP GET

First we learn about sending HTTP GET requests. Simply this means, we are sending our data by appending to the server URL. Also I’m going to show you two ways of sending data in iOS.

  1. Synchronous – happening at the same time
  2. Asynchronous – Not happening at the same time. Waiting in a queue.

So in the first block of code, you will learn how to send a HTTP GET request to your localhost in synchronous manner and gather the response data inside the same method.

- (void)sendHttpGet {
 NSLog(@"%s - %d", __PRETTY_FUNCTION__, __LINE__);
 
 /*
 * String literal that hardcode the localhost server URL which handles the HTTP GET request
 */
 NSString *urlStr = @"http://127.0.0.1/restapi/index.php?name=Anuja";
 
 /*
 * URLWithString - Returns an NSURL object initialized with URLString.
 * If the URL string was malformed or nil, returns nil.
 */
 NSURL *url = [NSURL URLWithString:urlStr];
 
 /*
 * requestWithURL - Creates and returns a URL request for a specified URL with default cache policy (NSURLRequestUseProtocolCachePolicy) and timeout value (60 seconds).
 *
 */
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 
 NSURLResponse *response;
 NSError *error;
 
 /*
 * sendSynchronousRequest:returningResponse:error: - Performs a synchronous load of the specified URL request.
 * Returns the downloaded data for the URL request. 
 * Returns nil if a connection could not be created or if the download fails.
 */
 NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 
 NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
 NSLog(@"%s - %d # responseStr = %@", __PRETTY_FUNCTION__, __LINE__, responseStr);
}

I’m not going to explain the code here, because it is explained using comments and you can download the full source code from the GitHub repository link that I’m providing at the end of this post.

From the following block of code, you will be able to learn how to send HTTP GET request to your localhost as asynchronously. This time, you will gather response data inside the block of request class method.

- (void)sendHttpGetAsync {
 NSLog(@"%s - %d", __PRETTY_FUNCTION__, __LINE__);
 
 NSString *urlStr = @"http://127.0.0.1/restapi/index.php?name=AnujA";
 
 NSURL *url = [NSURL URLWithString:urlStr];
 
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 
 NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
 
 /*
 * sendAsynchronousRequest:queue:completionHandler: - Loads the data for a URL request and executes a handler block on an operation queue when the request completes or fails.
 */
 [NSURLConnection sendAsynchronousRequest:request queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
 
 NSString *responseStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 NSLog(@"%s - %d # responseStr = %@", __PRETTY_FUNCTION__, __LINE__, responseStr);
 }];
}

In above two examples, you have send requests using default HTTP headers. If your are not familiar about these header types please visit this WiKi link.

In the next sample code we will see how to send custom header type. Most of the time these custom headers are using for security reasons. So in this example I’m going to add my own header type to the HTTP GET request. So if the server side is not handle to accept this header, you will get an authentication error. You can get the server side code at the end of this post.

- (void)sendHttpGetMutable {
 NSLog(@"%s - %d", __PRETTY_FUNCTION__, __LINE__);
 
 NSString *urlStr = @"http://127.0.0.1/restapi/index.php?name=anuja";
 
 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
 
 [request setURL:[NSURL URLWithString:urlStr]];
 
 [request setHTTPMethod:@"GET"];
 
 /*
 * addValue:forHTTPHeaderField: - Adds an HTTP header to the receiver’s HTTP header dictionary.
 * This is the way we add custom headers to a HTTP request.
 * Otherwise we use setValue:forHTTPHeaderField: method to set values to existing headers.
 */
 [request addValue:@"apiuser" forHTTPHeaderField:@"X-USERNAME"];
 
 /*
 * allHTTPHeaderFields - Listing all of the receiver’s HTTP header fields. (read-only)
 */
 NSLog(@"%s - %d # allHTTPHeaderFields = %@", __PRETTY_FUNCTION__, __LINE__, [request allHTTPHeaderFields]);
 
 NSURLResponse *response;
 NSError *error;
 
 NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 
 NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
 NSLog(@"%s - %d # responseStr = %@", __PRETTY_FUNCTION__, __LINE__, responseStr);
}

Having said that, we will move to study our next HTTP method call, which is;

HTTP POST

So here you will send your data in the body part of the HTTP request. For the first example of this, you will learn how to send HTTP POST request synchronously to your localhost with mutable header type. You will gather response inside the same method.

- (void)sendHttpPost {
 NSLog(@"%s - %d", __PRETTY_FUNCTION__, __LINE__);
 
 NSString *postMsg = @"name=AnujAroshA";
 NSString *urlStr = @"http://127.0.0.1/restapi/index.php";
 
 /*
 * dataUsingEncoding:allowLossyConversion: - Returns nil if flag is NO and the receiver can’t be converted without losing some information.
 */
 NSData *postData = [postMsg dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
 
 NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
 
 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
 
 [request setURL:[NSURL URLWithString:urlStr]];
 
 [request setHTTPMethod:@"POST"];
 
 [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
 
 /*
 * Sets value for default header field
 */
 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 
 /*
 * Add customer header field and value
 */
 [request addValue:@"apiuser" forHTTPHeaderField:@"X-USERNAME"];
 
 [request setHTTPBody:postData];

 NSURLResponse *response;
 NSError *error;
 
 NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 
 NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
 NSLog(@"%s - %d # responseStr = %@", __PRETTY_FUNCTION__, __LINE__, responseStr);
}

As the final, we will learn how to send same above data and get the response using delegate method. Here you have to use NSURLConnectionDataDelegate in your header file. One special thing you have to remember for this method calling is, do not call the following method using a background thread. You can call all above methods in back ground but not this one. The reason is, here you are calling delegate:self which means you are expecting the result to be shown in your main UI thread.

- (void)sendHttpPostDataDelegate {
 NSLog(@"%s - %d", __PRETTY_FUNCTION__, __LINE__);
 
 NSString *postMsg = @"name=anujarosha";
 NSString *urlStr = @"http://127.0.0.1/restapi/index.php";
 
 NSData *postData = [postMsg dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
 
 NSString *postLength = [NSString stringWithFormat:@"%d",[postData length]];
 
 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
 
 [request setURL:[NSURL URLWithString:urlStr]];
 
 [request setHTTPMethod:@"POST"];
 
 [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
 
 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
 
 [request addValue:@"apiuser" forHTTPHeaderField:@"X-USERNAME"];
 
 [request setHTTPBody:postData];
 
 /*
 * Calling for the NSURLConnectionDataDelegate
 */
 NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
 
 if(conn) {
 NSLog(@"%s - %d # Connection Successful", __PRETTY_FUNCTION__, __LINE__);
 } else {
 NSLog(@"%s - %d # Connection could not be made", __PRETTY_FUNCTION__, __LINE__);
 }
}

You can receive data using – connection: didReceiveData: method. I’m not going to explain the server side PHP code inside this post because the post is lengthier than I expected. But you can read or download full source code from my GitHub repository link.

While you are reading the PHP code from above mentioned repository you will find some HTTP status codes. If you are wondering where those come from, please visit this WiKi link to study about HTTP status codes. This is all about for today lesson. Will meet with something new in next post. Till then, have a good coding time 🙂

Advertisements

About AnujAroshA

Working as a Senior Software Engineer. Specialized in iOS application development. A simple person :)
This entry was posted in iOS, PHP examples and tagged , , , , . Bookmark the permalink.

2 Responses to How to send HTTP requests from iOS

  1. Keep doing good work… Well done

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s