Alamofire vs URLSession: a comparison for networking in Swift

Alamofire and URLSession both help you to make network requests in Swift. The URLSession API is part of the foundation framework, whereas Alamofire needs to be added as an external dependency. Many developers doubt whether it’s needed to include an extra dependency on something basic like networking in Swift. In the end, it’s perfectly doable to implement a networking layer with the great URLSession API’s which are available nowadays.

This blog post is here to compare both frameworks and to find out when to add Alamofire as an external dependency.

This shows the real power of Alamofire as the framework makes a lot of things easier.

What is Alamofire?

Alamofire - Elegant Networking in Swift

Where URLSession can be found within the standard Foundation framework, we have to go on Github to find Alamofire. It’s an open sourced framework and owned by the Alamofire Software Foundation. The framework is very popular as you can read from the stats at the moment of writing this blog post:

  • 164 contributors
  • 30K+ stars
  • 42 million (!!) downloads according to CocoaPods stats and 600K+ apps which are using it

These stats make it one of the most popular Swift frameworks available. It’s a well maintained, often used framework which should make it easier to implement networking into your apps.

Alamofire is named after the Alamo Fire flower, a hybrid variant of the Bluebonnet, the official state flower of Texas.

Alamofire and URLSession compared

I’ve asked my followers on Twitter what they prefer to use: Alamofire or URLSession.

It turns out that there is a clear separation between developers who prefer to use Alamofire or URLSession. A big question here is if they only prefer it or whether they actually choose to go with the framework of choice as well.

Alamofire is being advertised as “Elegant Networking in Swift” which gives away its intention a bit already. It’s a layer on top of URLSession with the goal to make common networking features easier to implement.

Features which are easier to implement with Alamofire

Alamofire contains a lot of extra logic apart from simply building a networking request. These features can make a difference and can sometimes save you a lot of time compared to building them yourself.

The list of features advertised on their repository readme is long, from which only a few of them really add unique extra value:

  • Certificate pinning. It can take some time to sort this out and build this yourself.
  • Requests retrying. When a request fails for example because of an authentication failure, you can easily refresh your authentication token and invoke the same request again without touching the implementation code.

Apart from these features, the syntax for building up requests is a lot more elegant and easier to use. It saves you from a lot extra code and makes validation and error handling a lot easier.

Often seen as an advantage is the network reachability manager. However, since iOS 12 we can make use of the new NWPathMonitor API as well.

Building a network request compared

Let’s say we have an API which allows us to create a new board with a title “New York Highlights”. For this, using Alamofire the code is very easy:

AF.request("https://api.mywebserver.com/v1/board", method: .get, parameters: ["title": "New York Highlights"])
    .validate(statusCode: 200..<300)
    .responseDecodable { (response: DataResponse) in
        switch response.result {
        case .success(let board):
            print("Created board title is \(board.title)") // New York Highlights
        case .failure(let error):
            print("Board creation failed with error: \(error.localizedDescription)")
        }
}

Doing exactly the same with the URLSession API requires a bit more of work.

enum Error: Swift.Error {
    case requestFailed
}

// Build up the URL
var components = URLComponents(string: "https://api.mywebserver.com/v1/board")!
components.queryItems = ["title": "New York Highlights"].map { (key, value) in
    URLQueryItem(name: key, value: value)
}

// Generate and execute the request
let request = try! URLRequest(url: components.url!, method: .get)
URLSession.shared.dataTask(with: request) { (data, response, error) in
    do {
        guard let data = data,
            let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode,
            error == nil else {
            // Data was nil, validation failed or an error occurred.
            throw error ?? Error.requestFailed
        }
        let board = try JSONDecoder().decode(Board.self, from: data)
        print("Created board title is \(board.title)") // New York Highlights
    } catch {
        print("Board creation failed with error: \(error.localizedDescription)")
    }
}

This shows the real power of Alamofire as the framework makes a lot of things easier:

  • The request is build up within a single initializer
  • A URL encoder is encoding parameters by default
  • Validation is done inline with a simple one-liner and converts into a strongly typed error if validation fails. The response result enum will return this error inside the failure case.
  • A generic completion callback makes it easy to decode the response into our custom Board type

This only could already be a reason to chose for Alamofire and make your life easier. With using URLSession you’re likely ending up making your own wrapper, which requires maintenance and testing. At first, this might seem to be a better decision compared to adding a new dependency, but as projects evolve it could easily be that your own networking layer evolves and gets more complex.

How bad would it be to add Alamofire as a dependency?

Let’s make it clear that you have to be careful when adding an external dependency to your project. When it’s not maintained, tested or not used a lot, it can add a possible risk to your project. In the end, you might have to continue the development yourself.

In the case of Alamofire, you don’t really have to worry about that. The framework is well maintained, tested, and used. The framework is quite small and makes it way more elegant to write network requests.

Conclusion: How to make the decision?

Alamofire is often compared to AFNetworking, the Objective-C equivalent framework for networking. At the time, networking was a lot harder without the URLsession API which only exists since iOS 7. Therefore, it was way more obvious to chose for a framework like AFNetworking to make your life a bit easier.

Nowadays, looking at the URLSession APIs available, it’s a lot easier to build up network requests. However, doing so will likely move you towards building your own networking layer on top of URLSession. This layer needs to be tested and can potentially grow towards a more complex layer as your project evolves.

With that in mind, taking the fact that Alamofire is well maintained and used by a lot of projects, you’re probably saving yourself a lot of hassle and time by adding Alamofire as a dependency.

This blog post is comparing URLSession to Alamofire 5, which is in beta at the moment of writing. You can read more about this release here.