@@ -10,33 +10,132 @@ Alamofire 3.0 officially supports iOS 8+, Mac OS X 10.9+, watchOS 2.0, Xcode 7 a
## Reasons for Bumping to 3.0
TODO
The [Alamofire Software Foundation](https://github.com/Alamofire/Foundation)(ASF) tries to do everything possible to avoid MAJOR version bumps. We realize the challenges involved with migrating large projects from one MAJOR version to another. With that said, we also want to make sure we're always producing the highest quality APIs and features possible.
After releasing Alamofire 2.0, it became clear that the response serialization system still had some room for improvement. After much debate, we decided to strictly follow semver and move forward with all the core logic changes becoming Alamofire 3.0. We've also made some fairly significant changes that should give us more flexibility moving forward to help avoid the need for MAJOR version bumps to maintain backwards compatibility.
## Benefits of Upgrading
TODO
The benefits of upgrading can be summarized as follows:
* No more casting a response serializer `error` from an `ErrorType` to an `NSError`.
* Original server data is now ALWAYS returned in all response serializers regardless of whether the result was a `.Success` or `.Failure`.
* Custom response serializers are now ALWAYS called regardless of whether an `error` occurred.
* Custom response serializers are now passed in the `error` allowing you to switch between different parsing schemes if necessary.
* Custom response serializers can now wrap up any Alamofire `NSError` into a `CustomError` type of your choosing.
*`Manager` initialization can now accept custom `NSURLSession` or `SessionDelegate` objects using dependency injection.
---
## Breaking API Changes
TODO
Alamofire 3.0 contains some breaking API changes to the foundational classes supporting the response serialization system. It is important to understand how these changes affect the common usage patterns.
### Result Type
TODO
The `Result` type was introduced in Alamofire 2.0 as a single generic parameter with the following signature:
```swift
publicenumResult<Value>{
caseSuccess(Value)
caseFailure(NSData?,ErrorType)
}
```
While this was a significant improvement on the behavior of Alamofire 1.0, there was still room for improvement. By defining the `.Failure` case to take an `ErrorType`, all consumers needed to cast the `ErrorType` to some concrete object such as an `NSError` before being able to interact with it. This was certainly not ideal. Additionally, by only allowing the `NSData?` from the server to be appended in a `.Failure` case, it was not possible to access the original server data in a `.Success` case.
In Alamofire 3.0, the `Result` type has been redesigned to be a double generic type that does not store the `NSData?` in the `.Failure` case.
```swift
publicenumResult<Value,Error:ErrorType>{
caseSuccess(Value)
caseFailure(Error)
}
```
These changes allow Alamofire to return the original server data in both cases. It also removes the requirement of having to cast the `ErrorType` when working with the `.Failure` case error object.
### Response
TODO
In order to avoid constantly having to change the response serializer completion closure signatures, ALamofire 3.0 introduces a `Response` struct. All response serializers (with the exception of `response`) return a generic `Response` struct.
```swift
publicstructResponse<Value,Error:ErrorType>{
/// The URL request sent to the server.
publicletrequest:NSURLRequest?
/// The server's response to the URL request.
publicletresponse:NSHTTPURLResponse?
/// The data returned by the server.
publicletdata:NSData?
/// The result of response serialization.
publicletresult:Result<Value,Error>
}
```
This unifies the signature of all response serializer completion closures by only needing to specify a single parameter rather than three or four. If another major release of Alamofire needs to modify the signature, thankfully the number of parameters in all response serializers will NOT need to change. Given the fact that the Swift compiler can present some fairly misleading compiler errors when the arguments are not correct, this should help alleviate some painful updates between MAJOR version bumps of Alamofire.
### Response Serializers
TODO
The biggest change in Alamofire 3.0 are the response serializers. They are now powered by the new `Response` struct and updated `Result` type. These two generic classes make it VERY easy to interact with the response serializers in a consistent, type-safe manner.
debugPrint(response)// prints detailed description of all response properties
print(response.request)// original URL request
print(response.response)// URL response
print(response.data)// server data
print(response.result)// result of response serialization
ifletJSON=response.result.value{
print("JSON: \(JSON)")
}
}
```
Besides the single response parameter in the completion closure, the other major callouts are that the original server data is always available whether the `Result` was a `.Success` or `.Failure`. Additionally, both the `value` and `error` of the `Result` type are strongly typed objects thanks to the power of generics. All default response serializer errors will be an `NSError` type. Custom response serializers can specify any custom `ErrorType`.
#### Response Serializer Type
TODO
For those wishing to create custom response serializer types, you'll need to familiarize yourself with the new `ResponseSerializerType` protocol and generic `ResponseSerializer` struct.
```swift
publicprotocolResponseSerializerType{
/// The type of serialized object to be created by this `ResponseSerializerType`.
typealiasSerializedObject
/// The type of error to be created by this `ResponseSerializer` if serialization fails.
typealiasErrorObject:ErrorType
/**
A closure used by response handlers that takes a request, response, data and error and returns a result.
All the possible information about the `Request` is now passed into the `serializeResponse` closure. In Alamofire 3.0, the `serializeResponse` closure is ALWAYS called whether an error occurred or not. This is for several reasons.
1. Passing the error into the response serializer allows the implementation to switch parsing schemes based on what error occurred. For example, some APIs will return different payload schemas when certain errors occur. The new design allows you to switch on the error type and use different parsing logic.
2. Any error produced by Alamofire will always be an `NSError`. If your custom response serializer returns `CustomError` types, then the `NSError` returned by Alamofire must be converted into a `CustomError` type. This makes it MUCH easier to wrap Alamofire errors in your own `CustomError` type objects.
> This is also required for all the generics logic to work properly.
### Validation Result
The `ValidationResult` enumeration in Alamofire 3.0 has been updated to take an `NSError` in the `.Failure` case. The reasoning for this change is that all Alamofire errors generated need to be `NSError` types. If not, it introduces the need to cast all error objects coming from Alamofire at the response serializer level.
```swift
publicenumValidationResult{
caseSuccess
caseFailure(NSError)
}
```
> If you are extending the `Request` type in any way that can produce an error, that error always needs to be of type `NSError`. If you'd like to wrap the error into a `CustomError` type, it should be wrapped in a custom response serializer implementation.
---
...
...
@@ -44,12 +143,44 @@ TODO
### Dependency Injection
TODO
Alamofire 3.0 leverages [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) to allow some powerful new customizations to take place for the URL session and delegate.
#### Session Delegate
TODO
In previous versions of Alamofire, the `SessionDelegate` was automatically created by the `Manager` instance. While this is convenient, it can be problematic for background sessions. One may need to hook up the task override closures before instantiating the URL session. Otherwise the URL session delegate could be called before the task override closures are able to be set.
In Alamofire 3.0, the `Manager` initializer adds the ability to provide a custom `SessionDelegate` object with the task override closures already set using dependency injection. This greatly increases the flexibility of Alamofire in regards to background sessions.
Alamofire 3.0 also adds the ability to use dependency injection to provide a custom `NSURLSession` to the `Manager` instance. This provides complete control over the URL session initialization if you need it allowing `NSURLSession` subclasses for various kinds of testing and DVR implementations.