Tutorial: How To Use iOS NSURLConnection By Example

Most of the apps you’ll build will have to fetch some sort of data through the network whether it’s as simple as high scores, a configuration file or more complex data such as a large movie catalogue. While there are a few ways you could fetch data in your iPhone application and more than a… View Article
Written by

Chris C

Last Updated on

04 Sep 2019

Most of the apps you’ll build will have to fetch some sort of data through the network whether it’s as simple as high scores, a configuration file or more complex data such as a large movie catalogue.

While there are a few ways you could fetch data in your iPhone application and more than a few networking libraries you could integrate, it’s still an asset to understand this handy class, NSURLConnection, since the libraries you’re using are probably using NSURLConnection under the hood. In the future, I hope to cover some of the networking libraries out there!


ARTICLE CONTENTS
1. An Asynchronous Example
2. A Synchronous Example
3. Performing a POST request
4. Example With Connection Timeout
5. Cache Policies


1. An Asynchronous Example

To fetch some data, we’ll follow these 3 basic steps:

1. Have our class conform to the NSURLConnectionDelegate protocol and declare a var to store the response data
2. Implement the NSURLConnectionDelegate protocol methods
3. Create an instance of NSURLRequest and NSURLConnection to kick off the request

The idea is that when you kick off the request in Step 3, you want to be notified of certain events that will happen, such as when the response comes back. And you’ll be handling such events via methods you implement in Step 2. In Step 1, you’re basically telling the system that you intend handle those NSURLConnection events.

Step 1.
In the class you’ll be using NSURLConnection, specify in the header file that it conforms to the NSURLConnectionDelegate protocol. Also declare an instance variable to hold the response data.

@interface ViewController : UIViewController<NSURLConnectionDelegate>
{
    NSMutableData *_responseData;
}

Step 2.
Next, in the implementation file, you’ll implement the NSURLConnection protocol methods. In the comments in the code block below, you can see what each protocol method is used for:

#pragma mark NSURLConnection Delegate Methods

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    // A response has been received, this is where we initialize the instance var you created
    // so that we can append data to it in the didReceiveData method
    // Furthermore, this method is called each time there is a redirect so reinitializing it
    // also serves to clear it
    _responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the new data to the instance variable you declared
    [_responseData appendData:data];
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {
    // Return nil to indicate not necessary to store a cached response for this connection 
    return nil;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    // The request is complete and data has been received
    // You can parse the stuff in your instance variable now
    
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // The request has failed for some reason!
    // Check the error var
}

Step 3.
Now you’re finally ready to perform the asynchronous request. Create an instance of NSURLRequest, assign it the URL. Next, create an instance of a NSURLConnection and call the initWithRequest method, passing in your NSURLRequest.

// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];

// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Step 4.
What should happen is when your request is fired in Step 3, your handler, connection:didReceiveResponse will be hit first, indicating that the server has responded. Then the handler, connection:didReceiveData: will be hit several times. This is where you’ll append the latest data to the response data variable you declared in Step 1. Then finally, connectionDidFinishLoading: will be hit and you can parse the response data variable.

If you want to do a synchronous request, you can use the sendSynchronousRequest method of NSURLConnection.

2. A Synchronous Example

A synchronous request looks like the below:

// Send a synchronous request
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
                                          returningResponse:&response
                                                      error:&error];
    
if (error == nil)
{
    // Parse data here
}

A NSURLRequest is still required. The NSURLResponse and NSError vars are passed into the sendSynchronousReqeust method so when it returns, they will be populated with the raw response and error (if any). If you need to check for stuff like response codes you can do so via the “response” variable you pass in Line 6.

In Line 5, the request will be performed synchronously and the results assigned to the NSData variable. Before you work with the data, you should check that the error variable you passed in is still nil.

Async or Sync?
So should you perform an asynchronous request or use a synchronous one for your application? I find that in the large majority of times, I’m using the async request because otherwise the UI would be frozen while the synchronous request is doing its thing and that’s a big problem when the user is performing gestures or touches and the screen is unresponsive. Unless I’m firing off a request to do something really simple and quick like ping a server, I default to using the async pattern.

3. Performing a POST Request

To POST data, all you need to do is to use NSURLRequest like we did before previously, but this time you’ll set the HTTPMethod property to POST and you’ll assign the header fields and value in the body. Then we send it with NSURLConnection like before. The only difference is that this time, we’ll use an instance of NSMutableURLRequest because we need to modify and set it’s properties after initialization.

// Create the request.
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
    
// Specify that it will be a POST request
request.HTTPMethod = @"POST";
    
// This is how we set header fields
[request setValue:@"application/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

// Convert your data and set your request's HTTPBody property
NSString *stringData = @"some data";
NSData *requestBodyData = [stringData dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = requestBodyData;
    
// Create url connection and fire request
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

4. Example With Connection Timeout

If you want to set a timeout for your data retrieval, you can set the timeoutInterval property of your NSURLRequest. If you’re getting an error in XCode, ensure that you’re using an instance of NSMutableURLRequest because NSURLRequest is immutable.

// Setting a timeout
request.timeoutInterval = 20.0;

5. Cache Policies

To specify how your data should be cached locally, you can set a cache policy with your NSURLRequest. For example, the following snippet shows you how you can define a cache policy and a timeout.

// Initialize a request with an url cache policy and timeout.
NSURL *url = [NSURL URLWithString:@"http://google.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                cachePolicy:NSURLCacheStorageNotAllowed
                                            timeoutInterval:20.0];

If you don’t specify any caching policy with your NSURLRequest, then it will try to conform to whatever the protocol states. For example, with HTTP it will look at the server response headers and try to conform to what it dictates about caching. For more examples and information about NSURLConnection and caching, read my post on preventing caching problems with NSURLConnection.

Table of contents

    Get started for free

    Join over 2,000+ students actively learning with CodeWithChris
    69 Shares
    Share
    Tweet
    Pin
    Share
    Buffer