I'm happy to announce that we shipped Alamofire 5 beta 1 just over a week ago! This is the most significant release of Alamofire since the original in 2014! I've been working on this release on and off for a year now and I'm hoping you'll all take a look.
During the beta process I hope to gather feedback about migration and what we can do to help the process given the substantial renames for some of the APIs. Also, I'll be working to rewrite the documentation, including a migration guide, for modern Alamofire usage. So please, post your experiences adopting Alamofire 5 in a new topics here so we can help everyone make the migration.
So what does Alamofire 5 include? Well, here are the brief release notes, but I'll provide more detail here:
-
Rewritten Core: Over the years, the core types of Alamofire had grown far beyond their original designs. Much of this complexity was due to added features that touched all of the internal types, but some was due to issues with the original design. One of those issues was improper separation of concerns, where features were spread over multiple types, making it hard to understand and maintain over time. Another issue was haphazard thread-safety, as Alamofire was originally developed without the benefit of the Thread Sanitizer. This meant threading fixes were grafted on over the years and Alamofire's queue usage became hazardous to the system if the user tried to enqueue many requests at the same time, as every Alamofire
Request
had it's own queue, starving the system of resources. These rewritten types were able to rectify these issues by ensuring features were implemented in a single place, removing some complex but less used API, and reengineering Alamofire to use a single serial queue by default (as recommend in Modernizing Grand Central Dispatch from WWDC '17). I gave a presentation about this rewrite at dev/world 2018 in Melbourne, Australia. Overall these core types are faster, lighter, and smaller, while enabling more features and higher fidelity. -
Encodable
Parameters: Alamofire 5 now supports making requests with parameters fromEncodable
types. The implementation of this features includes aURLEncodedFormEncoder
for query and body encoding, largely based off of Vapor's type of the same name. This feature actually turned out to be more powerful than I had initially thought and it enables some very elegant possibilities for generic request abstractions. In fact, this is so powerful that we'll likely deprecate the older[String: Any]
parameter type in a later 5.X please and remove it in a future major release. -
Decodable
Responses: Alamofire 5 now supports generic response serialization ofDecodable
types. This is enabled through Alamofire's newDataDecoder
protocol, which abstracts over anyDecoder
that can decodeData
. This protocol allows you to use anyDecoder
with a single response method, maximizing flexibility for users which need to handle multiple response types, but at the same time defaulting to JSON for simplicity. -
Customizable Empty Response Handling: With the addition of
Decodable
response parsing, it was necessary for Alamofire to further enhance its empty response handling. This now includes exposing default response codes and request methods that may return empty responses as well as customization points for the built in response serializers. More flexibility is coming in a future release. -
HTTPHeaders
: Alamofire 5 includes simpleHTTPHeaders
andHTTPHeader
types to provide a single header API for all Alamofire and Foundation types, as well as convenience API for the most popular headers. - Certificate Pinning API Rewritten: Alamofire 5 rewrites the top level certificate pinning APIs while keeping the tested core implementations, creating a much more flexible design. With some of the changes enabled by the core type rewrite, Alamofire 5 can now return individual errors for certificate pinning failures, rather than the previous cancellation error that was easily confused with manual and automatic cancellation of tasks. This ability, along with the new protocol abstraction, enables powerful pinning capabilities that can return informative errors.
-
EventMonitor
: Alamofire 5 removes the previous closure API that was sometimes used to allow visibility into certain Alamofire events and replaces it with a standardized protocol abstraction that allows read-only access to 36 different events between bothURLSession
and Alamofire. This new abstraction allowed us to clean up our notification integration that was spread between multiple files into a single type that hooks into just the events that it needs. I've used this protocol on my own projects to enable easy logging of specific events in only a few lines of code. -
Asynchronous Request Pipeline: In Alamofire 5, all request creation is now asynchronous, allowing us to unify the awkwardly different multipart form encoding process with Alamofire's standard request creation process. This means that not only is multipart form encoding much simpler now (no encoding completion!) but request creation no longer blocks the calling thread. These changes also allow for full fidelity request retry. Previous versions of Alamofire lost data when converting incoming parameters into
URLRequest
s to be performed. Now, all parameters are maintained and every step of the process is retried whenRequestRetrier
s fire. -
Integrated
URLSessionTaskMetrics
: Alamofire 5 now captures and exposes allURLSessionTaskMetrics
for every request and removes the customTimeline
type that previously captured just a fraction of the same data. Not only are metrics captured for the lastURLSessionTask
issued, but since Alamofire 5 now captures all tasks associated with aRequest
, even during retry, the full history of associated values is available, including metrics. This makes is very easy to see the local performance of your requests without additional analytics libraries. -
Top Level API Removed from Global Namespace: Previous versions of Alamofire's documentation introduced users to making requests with the
Alamofire.request()
API. This dates back to version 1 and I think it reflects Mattt's belief that Swift would gain qualified module references, allowing users to refer to modules that weren't imported by just using the module name. This never came to pass, so this API was actually misleading. What was actually happening was thatimport Alamofire
was exposing globalrequest()
API everywhere, and theAlamofire.
wasn't actually necessary. This API, since it's valuable simple introduction to Alamofire, has been moved inside anAF
enum (attempt to use anAlamofire
enum failed due to collision with the module name) as static methods. -
RequestAdapter
Now Asynchronous: As part of the new asynchronous request pipeline, the requirement for theRequestAdapter
protocol was changed to be asynchronous as well, allowing adapters to grab async resources to add to a request. -
Removals:
- Older OS support: Alamofire 5 supports iOS 10+, macOS 10.12+, watchOS 3+, and tvOS 10+. Due to missing functionality in Foundation on Linux, Alamofire does not yet support Linux.
-
PropertyListResponseSerializer
andresponsePropertyList
, as we're pretty sure no one ever used them. - Support for
URLSessionStreamTask
, as that integration was never tested and yet had no issues filed against it, so we're pretty sure it was also never used. - Alamofire's closure API, which allowed users to mutate Alamofire's core types by setting closures that could override specific behaviors. While this was a final escape hatch for full control over Alamofire's interaction with
URLSession
, it was bug-prone and invasive. We hope to replace most of the functionality users gained by using the API by offering specific functionality that's better, but that will come in the future. This includes things like full control over response caching at theURLSession
level, as well as client certificate verification.
As you can see, this is a huge list, so please ask questions in topics here, and if you find bugs or want to submit a feature, feel free to create issues and PRs on our GitHub.