|
|
@@ -29,6 +29,7 @@ Alamofire is an HTTP networking library written in Swift.
|
|
|
|
|
|
## Migration Guides
|
|
|
|
|
|
+- [Alamofire 3.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md)
|
|
|
- [Alamofire 2.0 Migration Guide](https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%202.0%20Migration%20Guide.md)
|
|
|
|
|
|
## Communication
|
|
|
@@ -142,11 +143,16 @@ Alamofire.request(.GET, "http://httpbin.org/get")
|
|
|
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
|
|
|
- .response { request, response, data, error in
|
|
|
- print(request)
|
|
|
- print(response)
|
|
|
- print(error)
|
|
|
- }
|
|
|
+ .responseJSON { response in
|
|
|
+ print(response.request) // original URL request
|
|
|
+ print(response.response) // URL response
|
|
|
+ print(response.data) // server data
|
|
|
+ print(response.result) // result of response serialization
|
|
|
+
|
|
|
+ if let JSON = response.result.value {
|
|
|
+ print("JSON: \(JSON)")
|
|
|
+ }
|
|
|
+ }
|
|
|
```
|
|
|
|
|
|
> Networking in Alamofire is done _asynchronously_. Asynchronous programming may be a source of frustration to programmers unfamiliar with the concept, but there are [very good reasons](https://developer.apple.com/library/ios/qa/qa1693/_index.html) for doing it this way.
|
|
|
@@ -157,30 +163,39 @@ Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
|
|
|
|
|
|
**Built-in Response Methods**
|
|
|
|
|
|
-- `response()`
|
|
|
+- `responseData()`
|
|
|
- `responseString(encoding: NSStringEncoding)`
|
|
|
- `responseJSON(options: NSJSONReadingOptions)`
|
|
|
- `responsePropertyList(options: NSPropertyListReadOptions)`
|
|
|
|
|
|
-#### Response String Handler
|
|
|
+#### Response Data Handler
|
|
|
+
|
|
|
+```swift
|
|
|
+Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
|
|
|
+ .responseData { response in
|
|
|
+ print(request)
|
|
|
+ print(response)
|
|
|
+ print(data)
|
|
|
+ print(error)
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+#### Response String Handler
|
|
|
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get")
|
|
|
- .responseString { _, _, result in
|
|
|
- print("Success: \(result.isSuccess)")
|
|
|
- print("Response String: \(result.value)")
|
|
|
+ .responseString { response in
|
|
|
+ print("Success: \(response.result.isSuccess)")
|
|
|
+ print("Response String: \(response.result.value)")
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-#### Response JSON Handler
|
|
|
+#### Response JSON Handler
|
|
|
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get")
|
|
|
- .responseJSON { _, _, result in
|
|
|
- print(result)
|
|
|
- debugPrint(result)
|
|
|
-
|
|
|
- print("Parsed JSON: \(result.value)")
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -190,11 +205,11 @@ Response handlers can even be chained:
|
|
|
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get")
|
|
|
- .responseString { _, _, result in
|
|
|
- print("Response String: \(result.value)")
|
|
|
+ .responseString { response in
|
|
|
+ print("Response String: \(response.result.value)")
|
|
|
}
|
|
|
- .responseJSON { _, _, result in
|
|
|
- print("Response JSON: \(result.value)")
|
|
|
+ .responseJSON { response in
|
|
|
+ print("Response JSON: \(response.result.value)")
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -271,7 +286,7 @@ enum ParameterEncoding {
|
|
|
|
|
|
```swift
|
|
|
let URL = NSURL(string: "http://httpbin.org/get")!
|
|
|
-var request = NSURLRequest(URL: URL)
|
|
|
+var request = NSMutableURLRequest(URL: URL)
|
|
|
|
|
|
let parameters = ["foo": "bar"]
|
|
|
let encoding = Alamofire.ParameterEncoding.URL
|
|
|
@@ -305,8 +320,8 @@ let headers = [
|
|
|
]
|
|
|
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get", headers: headers)
|
|
|
- .responseJSON { _, _, result in
|
|
|
- debugPrint(result)
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -339,12 +354,12 @@ Alamofire.upload(.POST, "http://httpbin.org/post", file: fileURL)
|
|
|
|
|
|
// This closure is NOT called on the main queue for performance
|
|
|
// reasons. To update your ui, dispatch to the main queue.
|
|
|
- dispatch_async(dispatch_get_main_queue) {
|
|
|
+ dispatch_async(dispatch_get_main_queue()) {
|
|
|
print("Total bytes written on main queue: \(totalBytesWritten)")
|
|
|
}
|
|
|
}
|
|
|
- .responseJSON { request, response, result in
|
|
|
- debugPrint(result)
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -353,7 +368,7 @@ Alamofire.upload(.POST, "http://httpbin.org/post", file: fileURL)
|
|
|
```swift
|
|
|
Alamofire.upload(
|
|
|
.POST,
|
|
|
- URLString: "http://httpbin.org/post",
|
|
|
+ "http://httpbin.org/post",
|
|
|
multipartFormData: { multipartFormData in
|
|
|
multipartFormData.appendBodyPart(fileURL: unicornImageURL, name: "unicorn")
|
|
|
multipartFormData.appendBodyPart(fileURL: rainbowImageURL, name: "rainbow")
|
|
|
@@ -361,8 +376,8 @@ Alamofire.upload(
|
|
|
encodingCompletion: { encodingResult in
|
|
|
switch encodingResult {
|
|
|
case .Success(let upload, _, _):
|
|
|
- upload.responseJSON { request, response, result in
|
|
|
- debugPrint(result)
|
|
|
+ upload.responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
case .Failure(let encodingError):
|
|
|
print(encodingError)
|
|
|
@@ -412,7 +427,7 @@ Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destinati
|
|
|
print("Total bytes read on main queue: \(totalBytesRead)")
|
|
|
}
|
|
|
}
|
|
|
- .response { request, response, _, error in
|
|
|
+ .responseData { response in
|
|
|
print(response)
|
|
|
}
|
|
|
```
|
|
|
@@ -421,9 +436,9 @@ Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destinati
|
|
|
|
|
|
```swift
|
|
|
Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
|
|
|
- .response { request, response, data, error in
|
|
|
+ .responseData { response in
|
|
|
if let
|
|
|
- data = data,
|
|
|
+ data = response.data,
|
|
|
resumeDataString = NSString(data: data, encoding: NSUTF8StringEncoding)
|
|
|
{
|
|
|
print("Resume Data: \(resumeDataString)")
|
|
|
@@ -437,10 +452,10 @@ Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destinati
|
|
|
|
|
|
```swift
|
|
|
let download = Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: destination)
|
|
|
-download.response { request, response, data, error in
|
|
|
+download.responseData { _ in
|
|
|
if let
|
|
|
resumeData = download.resumeData,
|
|
|
- resumeDataString = NSString(data: data, encoding: NSUTF8StringEncoding)
|
|
|
+ resumeDataString = NSString(data: resumeData, encoding: NSUTF8StringEncoding)
|
|
|
{
|
|
|
print("Resume Data: \(resumeDataString)")
|
|
|
} else {
|
|
|
@@ -470,8 +485,8 @@ let password = "password"
|
|
|
|
|
|
Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
|
|
|
.authenticate(user: user, password: password)
|
|
|
- .response { request, response, _, error in
|
|
|
- print(response)
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -487,8 +502,8 @@ let base64Credentials = credentialData.base64EncodedStringWithOptions(nil)
|
|
|
let headers = ["Authorization": "Basic \(base64Credentials)"]
|
|
|
|
|
|
Alamofire.request(.GET, "http://httpbin.org/basic-auth/user/password", headers: headers)
|
|
|
- .responseJSON { _, _, result in
|
|
|
- print(result)
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(result)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -502,8 +517,8 @@ let credential = NSURLCredential(user: user, password: password, persistence: .F
|
|
|
|
|
|
Alamofire.request(.GET, "https://httpbin.org/basic-auth/\(user)/\(password)")
|
|
|
.authenticate(usingCredential: credential)
|
|
|
- .response { request, response, _, error in
|
|
|
- print(response)
|
|
|
+ .responseJSON { response in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -517,8 +532,8 @@ By default, Alamofire treats any completed request to be successful, regardless
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
|
|
|
.validate(statusCode: 200..<300)
|
|
|
.validate(contentType: ["application/json"])
|
|
|
- .response { _, _, _, error in
|
|
|
- print(error)
|
|
|
+ .response { response in
|
|
|
+ print(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -529,11 +544,11 @@ Automatically validates status code within `200...299` range, and that the `Cont
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
|
|
|
.validate()
|
|
|
- .responseJSON { _, _, result in
|
|
|
- switch result {
|
|
|
+ .responseJSON { response in
|
|
|
+ switch response.result {
|
|
|
case .Success:
|
|
|
print("Validation Successful")
|
|
|
- case .Failure(_, let error):
|
|
|
+ case .Failure(let error):
|
|
|
print(error)
|
|
|
}
|
|
|
}
|
|
|
@@ -592,7 +607,7 @@ Alamofire.request(.GET, "http://httpbin.org/get")
|
|
|
|
|
|
```swift
|
|
|
let manager = Alamofire.Manager.sharedInstance
|
|
|
-manager.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/get")))
|
|
|
+manager.request(NSURLRequest(URL: NSURL(string: "http://httpbin.org/get")!))
|
|
|
```
|
|
|
|
|
|
Applications can create managers for background and ephemeral sessions, as well as new managers that customize the default session configuration, such as for default headers (`HTTPAdditionalHeaders`) or timeout interval (`timeoutIntervalForRequest`).
|
|
|
@@ -636,7 +651,7 @@ let manager = Alamofire.Manager(configuration: configuration)
|
|
|
|
|
|
The result of a `request`, `upload`, or `download` method is an instance of `Alamofire.Request`. A request is always created using a constructor method from an owning manager, and never initialized directly.
|
|
|
|
|
|
-Methods like `authenticate`, `validate`, and `response` return the caller in order to facilitate chaining.
|
|
|
+Methods like `authenticate`, `validate` and `responseData` return the caller in order to facilitate chaining.
|
|
|
|
|
|
Requests can be suspended, resumed, and cancelled:
|
|
|
|
|
|
@@ -654,24 +669,26 @@ For example, here's how a response handler using [Ono](https://github.com/mattt/
|
|
|
|
|
|
```swift
|
|
|
extension Request {
|
|
|
- public static func XMLResponseSerializer() -> GenericResponseSerializer<ONOXMLDocument> {
|
|
|
- return GenericResponseSerializer { request, response, data in
|
|
|
+ public static func XMLResponseSerializer() -> ResponseSerializer<ONOXMLDocument, NSError> {
|
|
|
+ return ResponseSerializer { request, response, data, error in
|
|
|
+ guard error == nil else { return .Failure(error!) }
|
|
|
+
|
|
|
guard let validData = data else {
|
|
|
let failureReason = "Data could not be serialized. Input data was nil."
|
|
|
let error = Error.errorWithCode(.DataSerializationFailed, failureReason: failureReason)
|
|
|
- return .Failure(data, error)
|
|
|
+ return .Failure(error)
|
|
|
}
|
|
|
|
|
|
do {
|
|
|
let XML = try ONOXMLDocument(data: validData)
|
|
|
return .Success(XML)
|
|
|
} catch {
|
|
|
- return .Failure(data, error as NSError)
|
|
|
+ return .Failure(error as NSError)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public func responseXMLDocument(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<ONOXMLDocument>) -> Void) -> Self {
|
|
|
+ public func responseXMLDocument(completionHandler: Response<ONOXMLDocument, NSError> -> Void) -> Self {
|
|
|
return response(responseSerializer: Request.XMLResponseSerializer(), completionHandler: completionHandler)
|
|
|
}
|
|
|
}
|
|
|
@@ -687,10 +704,12 @@ public protocol ResponseObjectSerializable {
|
|
|
}
|
|
|
|
|
|
extension Request {
|
|
|
- public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<T>) -> Void) -> Self {
|
|
|
- let responseSerializer = GenericResponseSerializer<T> { request, response, data in
|
|
|
+ public func responseObject<T: ResponseObjectSerializable>(completionHandler: Response<T, NSError> -> Void) -> Self {
|
|
|
+ let responseSerializer = ResponseSerializer<T, NSError> { request, response, data, error in
|
|
|
+ guard error == nil else { return .Failure(error!) }
|
|
|
+
|
|
|
let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
|
- let result = JSONResponseSerializer.serializeResponse(request, response, data)
|
|
|
+ let result = JSONResponseSerializer.serializeResponse(request, response, data, error)
|
|
|
|
|
|
switch result {
|
|
|
case .Success(let value):
|
|
|
@@ -702,10 +721,10 @@ extension Request {
|
|
|
} else {
|
|
|
let failureReason = "JSON could not be serialized into response object: \(value)"
|
|
|
let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
|
|
|
- return .Failure(data, error)
|
|
|
+ return .Failure(error)
|
|
|
}
|
|
|
- case .Failure(let data, let error):
|
|
|
- return .Failure(data, error)
|
|
|
+ case .Failure(let error):
|
|
|
+ return .Failure(error)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -727,9 +746,9 @@ final class User: ResponseObjectSerializable {
|
|
|
```
|
|
|
|
|
|
```swift
|
|
|
-Alamofire.request(.GET, "http://example.com/users/mattt")
|
|
|
- .responseObject { (_, _, result: Result<User>) in
|
|
|
- debugPrint(result)
|
|
|
+Alamofire.request(.GET, "https://example.com/users/mattt")
|
|
|
+ .responseObject { (response: Response<User, NSError>) in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -741,10 +760,12 @@ public protocol ResponseCollectionSerializable {
|
|
|
}
|
|
|
|
|
|
extension Alamofire.Request {
|
|
|
- public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<[T]>) -> Void) -> Self {
|
|
|
- let responseSerializer = GenericResponseSerializer<[T]> { request, response, data in
|
|
|
+ public func responseCollection<T: ResponseCollectionSerializable>(completionHandler: Response<[T], NSError> -> Void) -> Self {
|
|
|
+ let responseSerializer = ResponseSerializer<[T], NSError> { request, response, data, error in
|
|
|
+ guard error == nil else { return .Failure(error!) }
|
|
|
+
|
|
|
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
|
|
|
- let result = JSONSerializer.serializeResponse(request, response, data)
|
|
|
+ let result = JSONSerializer.serializeResponse(request, response, data, error)
|
|
|
|
|
|
switch result {
|
|
|
case .Success(let value):
|
|
|
@@ -753,10 +774,10 @@ extension Alamofire.Request {
|
|
|
} else {
|
|
|
let failureReason = "Response collection could not be serialized due to nil response"
|
|
|
let error = Error.errorWithCode(.JSONSerializationFailed, failureReason: failureReason)
|
|
|
- return .Failure(data, error)
|
|
|
+ return .Failure(error)
|
|
|
}
|
|
|
- case .Failure(let data, let error):
|
|
|
- return .Failure(data, error)
|
|
|
+ case .Failure(let error):
|
|
|
+ return .Failure(error)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -793,8 +814,8 @@ final class User: ResponseObjectSerializable, ResponseCollectionSerializable {
|
|
|
|
|
|
```swift
|
|
|
Alamofire.request(.GET, "http://example.com/users")
|
|
|
- .responseCollection { (_, _, result: Result<[User]>) in
|
|
|
- debugPrint(result)
|
|
|
+ .responseCollection { (response: Response<[User], NSError>) in
|
|
|
+ debugPrint(response)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
@@ -997,7 +1018,6 @@ let serverTrustPolicies: [String: ServerTrustPolicy] = [
|
|
|
]
|
|
|
|
|
|
let manager = Manager(
|
|
|
- configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
|
|
|
serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
|
|
|
)
|
|
|
```
|