The majority of apps require networking to connect to external services and data sources. ‘Networking’ means exchanging information via ‘http’ (Hypertext Transfer Protocol), one of the most used protocols. Every time you open your browser and retrieve or send data, you are using HTTP as the protocol. In this article you will learn how to work with networking in iOS by looking at the following options:
- HTTP
- Rest API
- NSURLSession: Networking without third party libraries
- Alamofire: Networking with a third party library to simplify the process
- A list of other networking libraries
If you are already familiar with the HTTP and REST APIs, skip to the NSURLSession
.
This article is part of a series of iOS related articles I am writing based on an application in development that will later be open sourced. The application makes use of data from Wikimedia Commons, and uses the site’s REST API to access this data.
HTTP
HTTP is one of the most popular protocols. If you are reading this article, you are using HTTP to retrieve the HTML page from the Sitepoint Servers. Your client (the browser) sends a request to the server and the server returns information about the requested resource(s). In the context of a mobile app, it will request lists of data, and the server responds with the requested data. These are called GET
requests.
Sometimes you have to post some data to the server from an app, for example an update. These are called POST
requests.
There are other types of requests (or verbs) as well, such as:
- GET
- POST
- HEAD
- PUT
- PATCH
If you’re interested in reading more about the HTTP protocol, I recommend this Wikipedia article.
REST API
A REST API is a simple and standard way to exchange data. You have some data on a server and want to retrieve it in an application. First you need to know how to structure your API, or ‘Application Programming Interface’ as the majority of APIs are a wrapper around a database.
As an example, you have a database table containing a list of books and your app needs to retrieve details on those books.
First you need a location to retrieve this data from. For this example, the domain is https://books.com/, and the API is at /api.
How should you represent your data on the API?
Data accessed through the API should be organized into collections and entities, in this case a collection is a group of books, represented as:
https://example.com/api/books
This url will return a collection of books. You can also implement pagination and search to this collection (https://example.com/api/v2/books?page=2
, https://example.com/api/v2/books?query='Jump Start PHP Environment'
). An entity is a specific book from the collection. It can be represented as https://example.com/api/v2/books/1
where 1
is an id.
Using the GET
, POST
and PUT
verbs from HTTP you can manipulate the entities and collections. Using the GET
verb, you can retrieve a book with an ID. For example, https://example.com/api/v2/books/7
. Using the POST
verb you can add a new book on the collection of books. You should also specify the required fields with other parameters.
Now you have a view of how to organize resources in an API, it’s time to decide how you will present the data. My favorite format is JSON as it helps two systems communicate in a manner that its not coupled with the language itself.
A JSON message might look like this:
{
"id": 7,
"userId": 20,
"title": "Jump Start PHP Environment",
"description": "Many entry level PHP developers want a quick path to glory, a shortcut to “knowing PHP.” Too many books and tutorials go straight into a pre-made, awful environment that just wants you to code, with no regard for security, version control, or other absolutely essential practices. This book is aimed at the absolute beginner who wants to start learning PHP, but aims to set you up with a thorough understanding of what makes for a good, modern, adaptable PHP environment before you start diving into PHP itself."
}
If your interested in building your own API I recommend this Sitepoint Article or if you are using WordPress and want to turn it into an API, this article.
NSURLSession
From iOS 7+ you can work with NSURLSession
for networking.
NSURLSession
is the ‘native’ way to work with remote data sets in Swift. Alamofire is built upon this technology. The following code is an example (Not production ready) of how to retrieve a login token from the Wikimedia Commons API.
class WCLoginApi {
static func nsurlAction(){
// Create a session configuration
let session = NSURLSession.sharedSession()
var stringUrl: String = "https://en.wikipedia.org/w/api.php"
stringUrl = stringUrl.stringByAppendingString("?action=query")
stringUrl = stringUrl.stringByAppendingString("&format=json")
stringUrl = stringUrl.stringByAppendingString("&meta=tokens")
stringUrl = stringUrl.stringByAppendingString("&type=login")
let url: NSURL = NSURL(string: stringUrl)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}
}
WCLoginApi.nsurlAction()
First you need session configuration, and in this example you retrieve the shared session configuration. This is a useful method if your app will repeatedly use the same general connection configuration, but not if you expect to make different requests.
After retrieving the configuration, you need to build the url and parameters. In this case the base url is https://en.wikipedia.org/w/api.php and the parameters are action
, format
, meta
and type
. GET
is used as the HTTP verb as you are retrieving a token from the server.
The creation of the task
to execute is the more complex part. After definition, the resume
method executes it asynchronously. When defining task
, a callback passed as an argument and print(dataString)
prints the data retrieved from the server.
Alamofire
Alamofire is an opinionated library that aims to make networking with iOS simpler. If you are planing to use more custom networking, for example using a different protocol, this library may not suit you. But if you are planing to use traditional REST APIs and simple networking, then I recommend trying Alamofire.
You can install Alamofire with CocoaPods, Carthage, or manually, so I recommend reading their installation guide for your preferred method.
Here is the earlier example re-written to use Alamofire:
import Alamofire
class WCLoginApi {
static func alamofireExample() -> Void
{
Alamofire.request(
.GET,
"https://en.wikipedia.org/w/api.php",
parameters: [
"action": "query",
"format": "json",
"meta": "tokens",
"type": "login"
]).responseJSON { response in
if let JSON = response.result.value {
if let loginTokenKey = JSON.objectForKey("query")?.objectForKey("tokens")?.objectForKey("logintoken") {
print(loginTokenKey)
}else{
print("Error to parse JSON")
}
}else{
print("Error with response")
}
}
}
}
WCLoginApi.alamofireExample()
To make a request you call the request
method that takes the HTTP verb as the second argument (these are a constants in Alamofire, .GET
in this case). The third argument is the base url without any arguments as a String
.
Next is a list of parameters (the same as in NSURLSession
). In this example you don’t encoded them as with the NSURLSession
‘s example, Alamofire builds them for you. You could build the url and parameter string yourself, but this is a better approach.
When dealing with Rest APIS, you will encounter different formats. The Wikimedia Commons API supports different formats, but as you know it will be in JSON, you can use the responseJSON
method. There are other call back methods for different formats.
I think this is simpler and more structured than the native iOS way. There are better ways to architect with the native method, but Alamofire makes it simpler. Alamofire isn’t limited to retrieving data but can also post and download data.
Alamofire allows you to change cache settings, check headers, chain responses (for example, checking the responseJSON
method with other response types), validate data from the response, authenticate users and more.
What Else?
Networking is a common task, so your options for simplifying the process are not limited to Alamofire. Here are some other libraries to consider:
- SwiftHTTP: A simple Swift wrapper around
NSURLSession
. - Moya: A Swift alternative to Alamofire.
- FSNetworking: Foursquare’s Objective-C networking implementation.
- Reach: A simple Swift library to check if you have network.
- iOS-netdiag: An Objective-C network diagnosis library.
In this article you learned the basics of iOS networking and REST Apis, the default iOS way to deal with networking, and Alamofire as an alternative.
As networking is a common task for every developer, I’d love to hear about your approach and what techniques or libraries have worked best for you.
Frequently Asked Questions (FAQs) on Networking in iOS
What are the key differences between URLSession and Alamofire for networking in iOS?
URLSession is a built-in framework provided by Apple for networking tasks. It is powerful and flexible, allowing you to perform HTTP requests, download and upload tasks, and more. URLSession also supports background downloads and uploads even when your app is not running.
On the other hand, Alamofire is a third-party library that simplifies networking tasks. It provides a clean and elegant syntax, making your code easier to read and maintain. Alamofire also offers additional features such as automatic JSON decoding, multipart form data support, and more. However, it adds an extra dependency to your project and may not be as efficient as URLSession for simple networking tasks.
How can I handle network errors in iOS?
Network errors can be handled using the completion handler of your networking tasks. The completion handler is a closure that gets called when the task is completed. It contains three parameters: data, response, and error. If an error occurs during the task, the error parameter will contain an NSError object describing the error. You can check if this object is nil to determine if an error occurred and handle it accordingly.
How can I test network connectivity in iOS?
You can use the Network framework provided by Apple to monitor network changes. The Network framework provides a NWPathMonitor class that you can use to monitor the network status. You can create an instance of NWPathMonitor and start it to begin monitoring. The pathUpdateHandler property of NWPathMonitor will be called whenever the network status changes.
How can I perform a POST request in iOS?
You can perform a POST request using URLSession. First, you need to create a URL object with the URL of your server. Then, you create a URLRequest object with this URL and set its HTTP method to “POST”. You can also set the HTTP body of the request with the data you want to send. Finally, you create a URLSessionDataTask with this request and call its resume method to start the task.
How can I parse JSON data in iOS?
You can parse JSON data using the JSONDecoder class provided by the Swift standard library. JSONDecoder provides a decode(:from:) method that you can use to decode a JSON object into a Swift object. You need to define a Swift struct that matches the structure of your JSON object and conforms to the Decodable protocol. Then, you can create an instance of JSONDecoder and call its decode(:from:) method to parse the JSON data.
How can I download a file in iOS?
You can download a file using URLSessionDownloadTask. This is a special type of URLSession task that is designed to download a file from a server. You create a URLSessionDownloadTask with a URL and call its resume method to start the download. The download task will download the file in the background and call your completion handler when the download is completed.
How can I upload a file in iOS?
You can upload a file using URLSessionUploadTask. This is a special type of URLSession task that is designed to upload a file to a server. You create a URLSessionUploadTask with a URL, a URLRequest, and the data you want to upload, and call its resume method to start the upload. The upload task will upload the file in the background and call your completion handler when the upload is completed.
How can I perform a multipart form data request in iOS?
Multipart form data requests can be performed using URLSession. You need to create a URLRequest with the URL of your server and set its HTTP method to “POST”. You also need to set the “Content-Type” header field to “multipart/form-data” and include a boundary string. The HTTP body of the request should contain the form data, each part separated by the boundary string.
How can I use WebSockets in iOS?
You can use WebSockets in iOS using the URLSessionWebSocketTask provided by URLSession. You create a URLSessionWebSocketTask with a URL and call its resume method to start the WebSocket connection. You can then send and receive messages using the send(_:completionHandler:) and receive(completionHandler:) methods of URLSessionWebSocketTask.
How can I cache network responses in iOS?
Network responses can be cached using the URLCache provided by URLSession. You can set the shared URLCache of URLSession with a custom URLCache that has a disk and memory capacity according to your needs. Then, URLSession will automatically cache responses according to their cache control headers. You can also manually store and retrieve responses from the cache using the storeCachedResponse(_:for:) and cachedResponse(for:) methods of URLCache.
![Aleksander Koko](https://uploads.sitepoint.com/wp-content/uploads/2014/05/1399090430me-96x96.jpg)
Aleksander is young developer who loves to play with the newest web technologies. In his free time, he reads about PHP, Firefox OS or experiments with a new language. Currently, his main interests are PHP design patterns, laravel, dart and cloud.