iPhone Application Development – Networking

Share this article

Fetching data over network is yet another important concept to become familiar with in the process of learning iOS application development. There are two basic APIs that help us in fetching the data over network either synchronously or asynchronously: NSURLConnection and NSURLSession. The latter was introduced as part of iOS7 SDK with additional features. There are many libraries that are built on top of these APIs. In this tutorial we will concentrate on these two APIs.

Key Takeaways

  • NSURLConnection and NSURLSession are two basic APIs that assist in fetching data over a network, either synchronously or asynchronously, with NSURLSession being introduced with additional features as part of iOS7 SDK.
  • NSURLConnection uses NSURLRequest class to create a request to a specified URL, specifying target URL, cache policy, HTTP request type, header fields, and post data, and then passes this request object to initialize NSURLConnection object and fire the request.
  • NSURLSession allows configuration of cache, cookie, and credential policies for each session, with three configuration settings: Default Session, Ephemeral Session, and Background session, and uses NSURLSessionTask objects for actual upload or download functions in a session.

NSURLConnection

The ‘NSURLRequest’ class helps in creating a request to the specified URL. It specifies the target URL and the cache policy that should be adopted while making the URL request. The HTTP request type, its header fields and post data can also be specified. So, we should create an instance of NSURLRequest with the required request information. This request object should be passed to initialize ‘NSURLConnection’ object and fire the request. The connection delegate should also be mentioned.

Asynchronous Connection

Sample GET Request

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://samplewebservice.com?x=1&y=2"]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Sample Post Request with HTTP Headers

NSMutableURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://samplewebservice.com"]];
    request.HTTPMethod = @"POST";
    [request setValue:@"text/plain" forHTTPHeaderField:@"Content-Type"];
    NSString *str = @"Post data";
    NSData *postData = [str dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = postData;
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Sample Request with cache Policy

NSMutableURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://samplewebservice.com"]
                                                    cachePolicy: NSURLRequestReloadIgnoringCacheData
                                                timeoutInterval:20.0];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
After the request is triggered we should implement the NSURLConnection delegate methods to receive the response data.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    
  //Declare a NSMutableData variable 'responseData' to hold the response from the server.
  //Initialize or reset the 'responseData' variable here.
    _responseData = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    // Append the data that we receive to the 'responseData' variable
    [self.responseData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  //The response data is fully received.
  //Parsing can be done here
        NSString *strResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
    NSLog(@"Response %@",strResponse);
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    // The request has failed due to some error
    NSLog(@"Error %@",[error description]);

}
There is one simple API, which could be used to trigger an asynchronous request.
[NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                               
                           //Parse the data here
                           
                           }];
This is how we should trigger and handle an asynchronous URL connection.

Synchronous Connection:

The ‘sendSynchronousRequest’ method of the ‘NSURLConnection’ class is used to make a synchronous call to the server.
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://samplewebservice.com"]];
    NSURLResponse * response = nil;
    NSError * error = nil;
    NSData * responsedata = [NSURLConnection sendSynchronousRequest:request
                                          returningResponse:&response
                                                      error:&error];
    
    if (error == nil)
    {
        // Parse response data here
    }
The response and the error variables are passed as arguments to the method. The response variable will be populated with the raw response if the connection is established successfully and the response is received. The error variable will be populated with the error details if the response data cannot be received. We should check if the error value is nil before we proceed with data parsing.

NSURLSession

With NSURLSession, we can configure cache, cookie and credential policies for each session rather than sharing it across the application. The NSURLSessionConfiguration object helps in specifying these policies and NSURLSession objects are instantiated with these configuration objects. The NSURLSessionConfiguration API comes with three configuration settings. Default Session: Configuration that uses global or shared cookie, cache and credential storage objects. Behaviour is similar to NSURLConnection. Ephemeral Session: Private Session Configuration that does not persist cookie, cache and credential storage objects. As the name indicates, the configuration settings are short living and are deleted when the session is invalidated. Background session: Similar to default session but upload or download of data can be performed even when the application is in suspended state. The actual upload or download functions in a session is done with the help of NSURLSessionTask objects. There are three types of session tasks Data Tasks: Data is sent and received in the form of NSData objects Download Tasks: Data is received in the form of file Upload Tasks: Data is usually sent in the form of file. Tasks can be created with completion handlers or delegates. Follow the steps below while creating a session
  1. Create a NSURLSessionConfiguration object. (Default/Ephemeral/Background)
  2. Set cache, protocol, cookie or credential policies and additional configuration settings with the help of the session configuration object created
  3. Create a NSURLSession object
  4. Create a NSURLSessionTask object (Data/Download/Upload)
  5. Implement the completion handler or the delegate methods

Sample Data task with Completion handler

Read the inline comments and try to understand the sample code given below
// Create a default session configuration object
    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    //Set policies and other session configuration parameters if required
    [sessionConfig setRequestCachePolicy:NSURLRequestReloadIgnoringCacheData];
    
    //Create a session with the configuration object
    //Set delegate to nil if you are going to use completion handler
    //Set the queue for the completion handlers
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
    
    //Create a NSURLRequest object with the webservice URL
    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://samplewebservice.com"]];
    //Create a data task object with the session and the request object
    // Implement the completion handler that should be triggered at the end of the request
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if(error == nil)
        {
            NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Response %@",strResponse);
        }
        
    }];
    
    //All the session tasks will be in the suspended state. //Call resume method on the tasks to trigger the request
    [dataTask resume];

Sample data task with delegates

Request Initiation

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    [sessionConfig setRequestCachePolicy:NSURLRequestReloadIgnoringCacheData];
    
    //Specify the custom delegate when creating the session
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURL *url = [NSURL URLWithString: @"http://www.example.com/"];
    NSURLSessionDataTask *dataTask = [session dataTaskWithURL: url];
    [dataTask resume];

Data Task Delegate Methods

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    //handle data here
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
    //Called when the data transfer is complete
    //Client side errors are indicated with the error parameter
}
Download tasks also has special delegates 1. Delegate to indicate that the download is complete. The file downloaded should be copied to a new location, as it will be deleted from the temporary location.
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;
2. Delegate to indicate the download progress. The progress indicator can be updated based on the amount of data downloaded.
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                           didWriteData:(int64_t)bytesWritten
                                      totalBytesWritten:(int64_t)totalBytesWritten
                              totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
3. Delegate called when the download gets resumed
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                      didResumeAtOffset:(int64_t)fileOffset
                                     expectedTotalBytes:(int64_t)expectedTotalBytes;
Upload task does not have special delegates but the delegate method below can be used to check the upload progress
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                                didSendBodyData:(int64_t)bytesSent
                                 totalBytesSent:(int64_t)totalBytesSent
                       totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

Conclusion

There are a lot more delegates and Network APIs you can explore by yourself. Hope this article has given some understanding on Networking concepts.

Frequently Asked Questions about iOS Application Development Networking

What is NSURLSessionConfiguration and how is it used in iOS application development networking?

NSURLSessionConfiguration is a class in iOS that allows you to configure the behavior and policies to use when uploading and downloading data. It is used to create a session configuration object that provides the behavior and policies to use when uploading and downloading data. You can customize a session configuration by adjusting its properties, such as timeout values and cache policies, before you use it to create a session.

How does the NSURLSessionConfiguration differ from NSURLConnection?

NSURLConnection is an older API that was used for networking tasks in iOS. However, NSURLSessionConfiguration is a more modern and flexible API that provides a higher level of control over networking operations. It allows for background downloads, better error handling, and more granular control over session configuration.

How can I configure NSURLSessionConfiguration in the NSObject class?

To configure NSURLSessionConfiguration in the NSObject class, you first need to create an instance of NSURLSessionConfiguration. Then, you can set various properties on this instance, such as timeoutIntervalForRequest or HTTPAdditionalHeaders, to customize the behavior of the session.

What is the purpose of the sendsynchronousrequest method in NSURLConnection?

The sendsynchronousrequest method in NSURLConnection is used to send a request and receive a response synchronously. This means that the method will block the current thread until the request is complete. This can be useful in certain situations, but it’s generally recommended to use asynchronous requests to avoid blocking the main thread.

How does NSURLSessionConfiguration handle caching?

NSURLSessionConfiguration provides a property called URLCache which allows you to specify a cache policy for your network requests. This can be used to control how responses are cached and when they should be revalidated.

What are the differences between the latest minor and objc language in NSURLSessionConfiguration?

The latest minor and objc language are different versions of the NSURLSessionConfiguration documentation. The latest minor version includes the most recent updates and changes, while the objc language version is specifically tailored for developers using Objective-C.

How can I use NSURLSessionConfiguration for background downloads?

To use NSURLSessionConfiguration for background downloads, you need to create a background session configuration using the backgroundSessionConfigurationWithIdentifier method. This will allow your app to continue downloading data even when it’s not running in the foreground.

What are the timeout values in NSURLSessionConfiguration?

The timeout values in NSURLSessionConfiguration are used to specify how long a network request should wait before giving up. There are two types of timeouts: timeoutIntervalForRequest, which sets the timeout for the entire request, and timeoutIntervalForResource, which sets the timeout for a single resource.

How can I set HTTP headers in NSURLSessionConfiguration?

You can set HTTP headers in NSURLSessionConfiguration by using the HTTPAdditionalHeaders property. This is a dictionary where the keys are the names of the HTTP headers and the values are the corresponding header values.

What is the difference between defaultSessionConfiguration and ephemeralSessionConfiguration in NSURLSessionConfiguration?

defaultSessionConfiguration returns a default configuration object that uses the disk-based cache, credential storage, and cookie storage. On the other hand, ephemeralSessionConfiguration returns a configuration object that doesn’t persist any data to disk. This means that caches, credential stores, and cookies are kept in memory and are lost when the session ends.

Kanya SrinisavanKanya Srinisavan
View Author
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week