Alamofire 2.0 is the latest major release of Alamofire, an HTTP networking library for iOS, Mac OS X and watchOS written in Swift. As a major release, following Semantic Versioning conventions, 2.0 introduces several API-breaking changes that one should be aware of.
This guide is provided in order to ease the transition of existing applications using Alamofire 1.x to the latest APIs, as well as explain the design and structure of new and changed functionality.
Alamofire 2.0 officially supports iOS 8+, Mac OS X 10.9+, Xcode 7 and Swift 2.0. If you'd like to use Alamofire in a project targeting iOS 7 and Swift 1.x, use the latest tagged 1.x release.
The biggest change between Alamofire 1.x and Alamofire 2.0 is Swift 2.0. Swift 2 brought many new features to take advantage of such as error handling, protocol extensions and availability checking. Other new features such as guard
and defer
do not affect the public APIs, but allowed us to create much cleaner implementations of the same logic. All of the source files, test logic and example code has been updated to reflect the latest Swift 2.0 paradigms.
It is not possible to use Alamofire 2.0 without Swift 2.0.
The most significant logic change made to Alamofire 2.0 is its new response serialization system leveraging Result
types. Previously in Alamofire 1.x, each response serializer used the same completion handler signature:
public func response(completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self {
return response(serializer: Request.responseDataSerializer(), completionHandler: completionHandler)
}
Alamofire 2.0 has redesigned the entire response serialization process to make it much easier to access the original server data without serialization, or serialize the response into a non-optional Result
type defining whether the Request
was successful.
The first response
serializer is non-generic and does not process the server data in any way. It merely forwards on the accumulated information from the NSURLSessionDelegate
callbacks.
public func response(
queue queue: dispatch_queue_t? = nil,
completionHandler: (NSURLRequest?, NSHTTPURLResponse?, NSData?, ErrorType?) -> Void)
-> Self
{
delegate.queue.addOperationWithBlock {
dispatch_async(queue ?? dispatch_get_main_queue()) {
completionHandler(self.request, self.response, self.delegate.data, self.delegate.error)
}
}
return self
}
Another important note of this change is the return type of data
is now an NSData
type. You no longer need to cast the data
parameter from an AnyObject?
to an NSData?
.
The second, more powerful response serializer leverages generics along with a Result
type to eliminate the case of the dreaded double optional.
public func response<T: ResponseSerializer, V where T.SerializedObject == V>(
queue queue: dispatch_queue_t? = nil,
responseSerializer: T,
completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<V>) -> Void)
-> Self
{
delegate.queue.addOperationWithBlock {
let result: Result<T.SerializedObject> = {
if let error = self.delegate.error {
return .Failure(self.delegate.data, error)
} else {
return responseSerializer.serializeResponse(self.request, self.response, self.delegate.data)
}
}()
dispatch_async(queue ?? dispatch_get_main_queue()) {
completionHandler(self.request, self.response, result)
}
}
return self
}
Alamofire.request(.GET, "http://httpbin.org/get")
.responseData { _, _, result in
print("Success: \(result.isSuccess)")
print("Response: \(result)")
}
Alamofire.request(.GET, "http://httpbin.org/get")
.responseString { _, _, result in
print("Success: \(result.isSuccess)")
print("Response String: \(result.value)")
}
Alamofire.request(.GET, "http://httpbin.org/get")
.responseJSON { _, _, result in
print(result)
debugPrint(result)
}
The Result
enumeration was added to handle the case of the double optional return type. Previously, the return value and error were both optionals. Checking if one was nil
did not ensure the other was also not nil
. This case has been blogged about many times and can be solved by a Result
type. Alamofire 2.0 brings a Result
type to the response serializers to make it much easier to handle success and failure cases.
public enum Result<Value> {
case Success(Value)
case Failure(NSData?, ErrorType)
}
There are also many other convenience computed properties to make accessing the data inside easy. The Result
type also conforms to the CustomStringConvertible
and CustomDebugStringConvertible
protocols to make it easier to debug.
While Alamofire still only generates NSError
objects, all Result
types have been converted to store ErrorType
objects to allow custom response serializer implementations to use any ErrorType
they wish. This also includes the ValidationResult
and MultipartFormDataEncodingResult
types as well.
In order to make it easier to deal with non-common scenarios, the URLRequestConvertible
protocol now returns an NSMutableURLRequest
. Alamofire 2.0 makes it much easier to customize the URL request after is has been encoded. This should only affect a small amount of users.
public protocol URLRequestConvertible {
var URLRequest: NSMutableURLRequest { get }
}
Encoding MultipartFormData
previous returned an EncodingResult
to encapsulate any possible errors that occurred during encoding. Alamofire 2.0 uses the new Swift 2.0 error handling instead making it easier to use. This change is mostly encapsulated internally and should only affect a very small subset of users.
The ParameterEncoding
enumeration implementation was previously hidden behind internal
and private
ACLs. Alamofire 2.0 opens up the queryComponents
and escape
methods to make it much easier to implement .Custom
cases.
In Alamofire 1.x, the ServerTrustPolicyManager
methods were internal making it impossible to implement any custom domain matching behavior. Alamofire 2.0 opens up the internals with a public
ACL allowing more flexible server trust policy matching behavior (i.e. wildcarded domains) through subclassing.
class CustomServerTrustPolicyManager: ServerTrustPolicyManager {
override func serverTrustPolicyForHost(host: String) -> ServerTrustPolicy? {
var policy: ServerTrustPolicy?
// Implement your custom domain matching behavior...
return policy
}
}
The global and Manager
download APIs now support parameters
and encoding
parameters to better support dynamic payloads used in background sessions. Constructing a download
request is now the same as constructing a data
request with the addition of a destination
parameter.
public func download(
method: Method,
_ URLString: URLStringConvertible,
parameters: [String: AnyObject]? = nil,
encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil,
destination: Request.DownloadFileDestination)
-> Request
{
return Manager.sharedInstance.download(
method,
URLString,
parameters: parameters,
encoding: encoding,
headers: headers,
destination: destination
)
}
Alamofire 2.0 adds support for creating NSURLSessionStreamTask
tasks for iOS 9 and OS X 10.11. It also extends the SessionDelegate
to support all the new NSURLSessionStreamDelegate
APIs.