Considering HTTPS requests from iOS / OS X ? — Here are few options!

Overview

At almost every level of networking, software can be divided into two categories: clients (programs that connect to other apps) and services (programs that other apps connect to).

Whenever a mobile application (or any client associated in a client-server relationship) needs data from server, it makes HTTP(s) request to server and fetches data. An HTTP request is a message consisting of a method for the remote server to execute, the object to operate on (the URL), message headers, and a message body. The methods are usually one of the following: GET, HEAD, PUT, POST, DELETE, TRACE, CONNECT or OPTIONS.

OS X and iOS provide a number of general-purpose APIs for making HTTP and HTTPS requests. (NOTE: For security reasons, HTTP should not be used for network requests. There are countless resources online to discuss about it.)

In this post, we’ll discuss various options available in OS x and iOS to make server requests from client application (iOS and OS X). (NOTE: This post only lists various alternatives to make the network requests provided/managed by Apple or OS. There are a lot of wrappers/adaptors (for e.g AFNetworking, Alamofire, RestKit, Overcoat etc) which makes it easier to do similar tasks, and also provide other features. However, the main idea of this post to look at various options available in iOS/OS X)

When choosing an API, we should first consider why we are making an HTTPS request, and what are the various options system provides to make such requests. Lets dive in….

NSURLConnection (Deprecated):

NSURLConnection got its start a decade ago, with the original release of Safari in 2003, as an abstraction on top of the Core Foundation / CFNetwork APIs. The name NSURLConnection actually refers to a group of the interrelated components that form the Foundation URL Loading System: NSURLRequest, NSURLResponse,NSURLProtocol, NSURLCache, NSHTTPCookieStorage, NSURLCredentialStorage, and NSURLConnection. For most of apps which request data from server, NSURLConnection was sufficient enough. If you need to download data from a URL and store the results in a file “yourself”, the NSURLConnection was a go to option. (See its successor NSURLSession for comparison between these)

NSURLDownload:

Available for OS X, NSURLDownload gives an application the ability to download the contents of a URL directly to disk. It provides an interface similar to NSURLConnection. NSURLDownload can also decode commonly used encoding schemes such as MacBinary, BinHex, and gzip. Unlike NSURLConnection, data downloaded using NSURLDownload is not stored in the cache system.

CFHTTPStream

The CFHTTPStream API is a C-language API that is part of the Core Foundation framework. Consider this option if any of following are true:

  • You have a strict requirement not to use Objective-C.
  • You need to override proxy settings.
  • You need to be compatible with a particular non-compliant server.

Otherwise you would generally use the NSURLSession or NSURLConnection APIs.

NKAssetDownload :

If you are writing a Newsstand app, NKAssetDownload is your best friend to download content in the background. It represents an asset that is being downloaded (or has downloaded) for an issue of a Newsstand application.

Using Sockets and Socket Streams

If you have specific needs, you can also write your own HTTP client implementation using socket or socket-stream APIs. Socket and stream programming generally falls into one of the following broad categories:

  • Packet-based communication — Programs that operate on one packet at a time, listening for incoming packets, then sending packets in reply. With packet-based communication, the only differences between clients and servers are the contents of the packets that each program sends and receives, and (presumably) what each program does with the data. The networking code itself is identical.
  • Stream-based clients — Programs that use TCP to send and receive data as two continuous streams of bytes, one in each direction.

The API you choose for socket-based connections depends on whether you are making a connection to another host or receiving a connection from another host. It also depends on whether you are using TCP or some other protocol. Here are a few factors to consider:

  • In OS X, if you already have networking code that is shared with non-Apple platforms, you can use POSIX C networking APIs and continue to use your networking code as-is (on a separate thread). If your program is based on a Core Foundation or Cocoa (Foundation) run loop, you can also use the Core Foundation CFStream API to integrate the POSIX networking code into your overall architecture on the main thread. Alternatively, if you are using Grand Central Dispatch (GCD), you can add a socket as a dispatch source. More info on POSIX can be found here.
  • In iOS, POSIX networking is discouraged because it does not activate the cellular radio or on-demand VPN. Thus, as a general rule, you should separate the networking code from any common data processing functionality and rewrite the networking code using higher-level APIs (For eg: NSURLSession).
  • For non-TCP connections, use POSIX or Core Foundation (CFSocket) C networking APIs.

The most appropriate times to use sockets directly are when you are developing a cross-platform tool or high-performance server software. In other circumstances, you typically should use a higher-level API.

NSURLSession

Introduced with iOS7 and OS X (10.9), NSURLSession API is highly asynchronous and was one of the most significant changes in iOS 7 and Mac OS X 10. It is a complete suite of networking API methods for uploading and downloading content via HTTP which includes classes like NSURLSession, NSURLSessionConfiguration, and three subclasses of NSURLSessionTask: NSURLSessionDataTask, NSURLSessionUploadTask, and NSURLSessionDownloadTask.

Types of Sessions (via NSURLSessionConfiguration)

The NSURLSession API supports three types of sessions, as determined by the type of configuration object used to create the session:

  • defaultSessionConfiguration: Creates a default configuration object that uses the disk-persisted global cache, credential and cookie storage objects. For security reasons, credentials are store in user’s keychain.
  • ephemeralSessionConfiguration: Similar to the default configuration, except that all session-related data is stored in memory (RAM). Thus, when app invalidates the session, they are purged automatically. Think of this as a “private” session.
  • backgroundSessionConfiguration: Similar to defaultSessionConfiguration but lets the session perform upload or download tasks in the background. Transfers continue even when the app itself is suspended or terminated.

Types of Tasks

NSURLSessionTask is an abstract class that denotes a task object. A session creates a task, which does the actual work of fetching data and downloading or uploading files.

There are three types of concrete session tasks:

Types of Tasks
  • NSURLSessionDataTask send and receive data using NSData objects. Data tasks are intended for short, often interactive requests from app to a server. Data tasks can return data to your app one piece at a time after each piece of data is received, or all at once through a completion handler.
  • NSURLSessionUploadTask send data in the form of a file, and support background uploads while the app is not running. Use this task to upload a file from disk to a web service, typically via a HTTP POST or PUT method.
  • NSURLSessionDownloadTask retrieve data in the form of a file, and support background downloads while the app is not running. Use this task to download a file from a remote service to a temporary file location.

All tasks are cancelable, and can be paused and resumed. When a download task is canceled, it has the option to create resume data, which can then be passed when creating a new download task to pick up where it left off. Session perform upload or download tasks in the background. Transfers continue even when the app itself is suspended or terminated.

The NSURLSession API provides a wide range of configuration options:

  • Private storage support for caches, cookies, credentials, and protocols in a way that is specific to a single session
  • Authentication, tied to a specific request (task) or group of requests (session)
  • File uploads and downloads by URL, which encourages separation of the data (the file’s contents) from the metadata (the URL and settings)
  • Configuration of the maximum number of connections per host
  • Per-resource timeouts that are triggered if an entire resource cannot be downloaded in a certain amount of time
  • Minimum and maximum TLS version support
  • Custom proxy dictionaries
  • Control over cookie policies (uses HTTPCookieStorage)
  • Control over security policies (via URLCredentialStorage)
  • Supports caching via NSURLCache
  • Ability to support custom protocols (using NSURLProtocol)
  • Control over HTTP pipelining behavior

Main Features:

  • Allows to perform upload or download tasks in the background. Transfers continue even when the app itself is suspended or terminated.
  • Supports both completion handler blocks, as well as custom delegate methods (task objects call those delegates’ methods with data as it is received from the server (or, for file downloads, when the transfer is complete).
  • We can configure session properties such as timeout values, caching policies and additional HTTP header.
  • Supports pausing, canceling, and resuming of tasks as well as UIKit’s multitasking API.
  • Apps can accomplish tasks that are relatively hard to accomplish (or simply not possible) with NSURLConnection, such as implementing private browsing.
  • Highly Asynchronous
  • It handles authentication on a connection basis instead of on a request basis, like NSURLConnection does.
  • Optimized to preserve battery life.

Conclusion

Although writing networking code can be easy, for all but the most trivial networking needs, writing good networking code is not.

For most of the applications, NSURLSession is very sophisticated to handle network related tasks (get, upload, download etc). Most of the popular networking libraries are built on top on NSURLSession.

Depending on your software’s needs, it may need to adapt to changing network performance, dropped network connections, connection failures, and other problems caused by the inherent unreliability of the Internet itself.

Unless app has special requirement, NSURLSession is way to go for network request on iOS & Mac OS X apps.

References:

Apple

Objc.io

Further Reading

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.