Skip to main content

Alamofire vs URLSession

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.

Comments

Popular posts from this blog

MVVM và VIPER: Con đường trở thành Senior

Trong bài viết trước chúng ta đã tìm hiểu về MVC và MVP để ứng dụng cho một iOS App đơn giản. Bài này chúng ta sẽ tiếp tục ứng dụng 2 mô hình MVVM và VIPER . Nhắc lại là ứng dụng của chúng ta cụ thể khi chạy sẽ như sau: Source code đầy đủ cho tất cả mô hình MVC, MVP, MVVM và VIPER các bạn có thể download tại đây . MVVM MVVM có thể nói là mô hình kiến trúc được rất nhiều các cư dân trong cộng đồng ưa chuộng. Điểm tinh hoa của kiến trúc này là ở ViewModel , mặc dù rất giống với Presenter trong MVP tuy nhiên có 2 điều làm nên tên tuổi của kiến trúc này đó là: ViewModel không hề biết gì về View , một ViewModel có thể được sử dụng cho nhiều View (one-to-many). ViewModel sử dụng Observer design pattern để liên lạc với View (thường được gọi là binding data , có thể là 1 chiều hoặc 2 chiều tùy nhu cầu ứng dụng). Chính đặc điểm này MVVM thường được phối hợp với các thư viện hỗ trợ Reactive Programming hay Event/Data Stream , đây là triết lý lập trình hiện đại và hiệu

Fileprivate vs private: Giải thích sự khác biệt

Fileprivate vs private in Swift: The differences explained Fileprivate and private are part of the access control modifiers in Swift. These keywords, together with internal, public, and open, make it possible to restrict access to parts of your code from code in other source files and modules. The private access level is the lowest and most restrictive level whereas open access is the highest and least restrictive. The documentation of Swift will explain all access levels in detail to you, but in this blog post, I’m going to explain the differences between two close friends: fileprivate and private. Build better iOS apps faster Looking for a great mobile CI/CD solution that has tons of iOS-specific tools, smooth code signing, and even real device testing? Learn more about Bitrise’s iOS specific solutions! Open access is the highest (least restrictive) access level and private access is the lowest (most restrictive) access level. This will improve readability and mak