Browse Source

Updated README sample code to 3.0 APIs and added a migration guide.

Christian Noon 10 years ago
parent
commit
cbc7df4fc5
2 changed files with 145 additions and 70 deletions
  1. 55 0
      Documentation/Alamofire 3.0 Migration Guide.md
  2. 90 70
      README.md

+ 55 - 0
Documentation/Alamofire 3.0 Migration Guide.md

@@ -0,0 +1,55 @@
+# Alamofire 3.0 Migration Guide
+
+Alamofire 3.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, 3.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 2.x to the latest APIs, as well as explain the design and structure of new and changed functionality.
+
+## Requirements
+
+Alamofire 3.0 officially supports iOS 8+, Mac OS X 10.9+, watchOS 2.0, 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.
+
+## Reasons for Bumping to 3.0
+
+TODO
+
+## Benefits of Upgrading
+
+TODO
+
+---
+
+## Breaking API Changes
+
+TODO
+
+### Result Type
+
+TODO
+
+### Response
+
+TODO
+
+### Response Serializers
+
+TODO
+
+#### Response Serializer Type
+
+TODO
+
+---
+
+## New Features
+
+### Dependency Injection
+
+TODO
+
+#### Session Delegate
+
+TODO
+
+#### URL Session 
+
+TODO

+ 90 - 70
README.md

@@ -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)
 )
 ```