Просмотр исходного кода

Moved the Manager class into a separate Swift file.

Christian Noon 10 лет назад
Родитель
Сommit
930a91d52e
3 измененных файлов с 385 добавлено и 359 удалено
  1. 6 0
      Alamofire.xcodeproj/project.pbxproj
  2. 0 359
      Source/Alamofire.swift
  3. 379 0
      Source/Manager.swift

+ 6 - 0
Alamofire.xcodeproj/project.pbxproj

@@ -7,6 +7,8 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		4CDE2C371AF8932A00BABAE5 /* Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDE2C361AF8932A00BABAE5 /* Manager.swift */; };
+		4CDE2C381AF8932A00BABAE5 /* Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDE2C361AF8932A00BABAE5 /* Manager.swift */; };
 		4CE2724F1AF88FB500F1D59A /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2724E1AF88FB500F1D59A /* ParameterEncoding.swift */; };
 		4CE272501AF88FB500F1D59A /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE2724E1AF88FB500F1D59A /* ParameterEncoding.swift */; };
 		4DD67C241A5C58FB00ED2280 /* Alamofire.h in Headers */ = {isa = PBXBuildFile; fileRef = F8111E3819A95C8B0040E7D1 /* Alamofire.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -52,6 +54,7 @@
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
+		4CDE2C361AF8932A00BABAE5 /* Manager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Manager.swift; sourceTree = "<group>"; };
 		4CE2724E1AF88FB500F1D59A /* ParameterEncoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParameterEncoding.swift; sourceTree = "<group>"; };
 		4DD67C0B1A5C55C900ED2280 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		F8111E3319A95C8B0040E7D1 /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -129,6 +132,7 @@
 			isa = PBXGroup;
 			children = (
 				F897FF4019AA800700AB5182 /* Alamofire.swift */,
+				4CDE2C361AF8932A00BABAE5 /* Manager.swift */,
 				4CE2724E1AF88FB500F1D59A /* ParameterEncoding.swift */,
 				F8111E3619A95C8B0040E7D1 /* Supporting Files */,
 			);
@@ -343,6 +347,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				4CE272501AF88FB500F1D59A /* ParameterEncoding.swift in Sources */,
+				4CDE2C381AF8932A00BABAE5 /* Manager.swift in Sources */,
 				4DD67C251A5C590000ED2280 /* Alamofire.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -352,6 +357,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				4CE2724F1AF88FB500F1D59A /* ParameterEncoding.swift in Sources */,
+				4CDE2C371AF8932A00BABAE5 /* Manager.swift in Sources */,
 				F897FF4119AA800700AB5182 /* Alamofire.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 0 - 359
Source/Alamofire.swift

@@ -85,365 +85,6 @@ extension NSURLRequest: URLRequestConvertible {
 
 // MARK: -
 
-/**
-    Responsible for creating and managing `Request` objects, as well as their underlying `NSURLSession`.
-*/
-public class Manager {
-
-    /**
-        A shared instance of `Manager`, used by top-level Alamofire request methods, and suitable for use directly for any ad hoc requests.
-    */
-    public static let sharedInstance: Manager = {
-        let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
-        configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
-
-        return Manager(configuration: configuration)
-    }()
-
-    /**
-        Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
-
-        :returns: The default header values.
-    */
-    public static let defaultHTTPHeaders: [String: String] = {
-        // Accept-Encoding HTTP Header; see http://tools.ietf.org/html/rfc7230#section-4.2.3
-        let acceptEncoding: String = "gzip;q=1.0,compress;q=0.5"
-
-        // Accept-Language HTTP Header; see http://tools.ietf.org/html/rfc7231#section-5.3.5
-        let acceptLanguage: String = {
-            var components: [String] = []
-            for (index, languageCode) in enumerate(NSLocale.preferredLanguages() as! [String]) {
-                let q = 1.0 - (Double(index) * 0.1)
-                components.append("\(languageCode);q=\(q)")
-                if q <= 0.5 {
-                    break
-                }
-            }
-
-            return join(",", components)
-        }()
-
-        // User-Agent Header; see http://tools.ietf.org/html/rfc7231#section-5.5.3
-        let userAgent: String = {
-            if let info = NSBundle.mainBundle().infoDictionary {
-                let executable: AnyObject = info[kCFBundleExecutableKey] ?? "Unknown"
-                let bundle: AnyObject = info[kCFBundleIdentifierKey] ?? "Unknown"
-                let version: AnyObject = info[kCFBundleVersionKey] ?? "Unknown"
-                let os: AnyObject = NSProcessInfo.processInfo().operatingSystemVersionString ?? "Unknown"
-
-                var mutableUserAgent = NSMutableString(string: "\(executable)/\(bundle) (\(version); OS \(os))") as CFMutableString
-                let transform = NSString(string: "Any-Latin; Latin-ASCII; [:^ASCII:] Remove") as CFString
-                if CFStringTransform(mutableUserAgent, nil, transform, 0) == 1 {
-                    return mutableUserAgent as NSString as! String
-                }
-            }
-
-            return "Alamofire"
-        }()
-
-        return ["Accept-Encoding": acceptEncoding,
-                "Accept-Language": acceptLanguage,
-                "User-Agent": userAgent]
-    }()
-
-    private let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)
-
-    /// The underlying session.
-    public let session: NSURLSession
-
-    /// The session delegate handling all the task and session delegate callbacks.
-    public let delegate: SessionDelegate
-
-    /// Whether to start requests immediately after being constructed. `true` by default.
-    public var startRequestsImmediately: Bool = true
-
-    /// The background completion handler closure provided by the UIApplicationDelegate `application:handleEventsForBackgroundURLSession:completionHandler:` method. By setting the background completion handler, the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` closure implementation will automatically call the handler. If you need to handle your own events before the handler is called, then you need to override the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` and manually call the handler when finished. `nil` by default.
-    public var backgroundCompletionHandler: (() -> Void)?
-
-    /**
-        :param: configuration The configuration used to construct the managed session.
-    */
-    required public init(configuration: NSURLSessionConfiguration? = nil) {
-        self.delegate = SessionDelegate()
-        self.session = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
-
-        self.delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
-            if let strongSelf = self {
-                strongSelf.backgroundCompletionHandler?()
-            }
-        }
-    }
-
-    deinit {
-        self.session.invalidateAndCancel()
-    }
-
-    // MARK: -
-
-    /**
-        Creates a request for the specified method, URL string, parameters, and parameter encoding.
-
-        :param: method The HTTP method.
-        :param: URLString The URL string.
-        :param: parameters The parameters. `nil` by default.
-        :param: encoding The parameter encoding. `.URL` by default.
-
-        :returns: The created request.
-    */
-    public func request(method: Method, _ URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL) -> Request {
-        return request(encoding.encode(URLRequest(method, URLString), parameters: parameters).0)
-    }
-
-
-    /**
-        Creates a request for the specified URL request.
-
-        If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
-
-        :param: URLRequest The URL request
-
-        :returns: The created request.
-    */
-    public func request(URLRequest: URLRequestConvertible) -> Request {
-        var dataTask: NSURLSessionDataTask?
-        dispatch_sync(queue) {
-            dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
-        }
-
-        let request = Request(session: session, task: dataTask!)
-        delegate[request.delegate.task] = request.delegate
-
-        if startRequestsImmediately {
-            request.resume()
-        }
-
-        return request
-    }
-
-    /**
-        Responsible for handling all delegate callbacks for the underlying session.
-    */
-    public final class SessionDelegate: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate {
-        private var subdelegates: [Int: Request.TaskDelegate] = [:]
-        private let subdelegateQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT)
-        private subscript(task: NSURLSessionTask) -> Request.TaskDelegate? {
-            get {
-                var subdelegate: Request.TaskDelegate?
-                dispatch_sync(subdelegateQueue) {
-                    subdelegate = self.subdelegates[task.taskIdentifier]
-                }
-
-                return subdelegate
-            }
-
-            set {
-                dispatch_barrier_async(subdelegateQueue) {
-                    self.subdelegates[task.taskIdentifier] = newValue
-                }
-            }
-        }
-
-        // MARK: NSURLSessionDelegate
-
-        /// NSURLSessionDelegate override closure for `URLSession:didBecomeInvalidWithError:` method.
-        public var sessionDidBecomeInvalidWithError: ((NSURLSession, NSError?) -> Void)?
-
-        /// NSURLSessionDelegate override closure for `URLSession:didReceiveChallenge:completionHandler:` method.
-        public var sessionDidReceiveChallenge: ((NSURLSession, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential!))?
-
-        /// NSURLSessionDelegate override closure for `URLSessionDidFinishEventsForBackgroundURLSession:` method.
-        public var sessionDidFinishEventsForBackgroundURLSession: ((NSURLSession) -> Void)?
-
-        public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
-            sessionDidBecomeInvalidWithError?(session, error)
-        }
-
-        public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)) {
-            if sessionDidReceiveChallenge != nil {
-                completionHandler(sessionDidReceiveChallenge!(session, challenge))
-            } else {
-                completionHandler(.PerformDefaultHandling, nil)
-            }
-        }
-
-        public func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
-            sessionDidFinishEventsForBackgroundURLSession?(session)
-        }
-
-        // MARK: NSURLSessionTaskDelegate
-
-        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:`.
-        public var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> (NSURLRequest!))?
-
-        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didReceiveChallenge:completionHandler:`.
-        public var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential!))?
-
-        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:session:task:needNewBodyStream:`.
-        public var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> (NSInputStream!))?
-
-        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`.
-        public var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)?
-
-        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didCompleteWithError:`.
-        public var taskDidComplete: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)?
-
-        public func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: ((NSURLRequest!) -> Void)) {
-            var redirectRequest: NSURLRequest? = request
-
-            if taskWillPerformHTTPRedirection != nil {
-                redirectRequest = taskWillPerformHTTPRedirection!(session, task, response, request)
-            }
-
-            completionHandler(redirectRequest)
-        }
-
-        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)) {
-            if taskDidReceiveChallenge != nil {
-                completionHandler(taskDidReceiveChallenge!(session, task, challenge))
-            } else if let delegate = self[task] {
-                delegate.URLSession(session, task: task, didReceiveChallenge: challenge, completionHandler: completionHandler)
-            } else {
-                URLSession(session, didReceiveChallenge: challenge, completionHandler: completionHandler)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, task: NSURLSessionTask, needNewBodyStream completionHandler: ((NSInputStream!) -> Void)) {
-            if taskNeedNewBodyStream != nil {
-                completionHandler(taskNeedNewBodyStream!(session, task))
-            } else if let delegate = self[task] {
-                delegate.URLSession(session, task: task, needNewBodyStream: completionHandler)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
-            if taskDidSendBodyData != nil {
-                taskDidSendBodyData!(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
-            } else if let delegate = self[task] as? Request.UploadTaskDelegate {
-                delegate.URLSession(session, task: task, didSendBodyData: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
-            if taskDidComplete != nil {
-                taskDidComplete!(session, task, error)
-            } else if let delegate = self[task] {
-                delegate.URLSession(session, task: task, didCompleteWithError: error)
-
-                self[task] = nil
-            }
-        }
-
-        // MARK: NSURLSessionDataDelegate
-
-        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveResponse:completionHandler:`.
-        public var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> (NSURLSessionResponseDisposition))?
-
-        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didBecomeDownloadTask:`.
-        public var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)?
-
-        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveData:`.
-        public var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)?
-
-        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:willCacheResponse:completionHandler:`.
-        public var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> (NSCachedURLResponse!))?
-
-        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: ((NSURLSessionResponseDisposition) -> Void)) {
-            var disposition: NSURLSessionResponseDisposition = .Allow
-
-            if dataTaskDidReceiveResponse != nil {
-                disposition = dataTaskDidReceiveResponse!(session, dataTask, response)
-            }
-
-            completionHandler(disposition)
-        }
-
-        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask) {
-            if dataTaskDidBecomeDownloadTask != nil {
-                dataTaskDidBecomeDownloadTask!(session, dataTask, downloadTask)
-            } else {
-                let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
-                self[downloadTask] = downloadDelegate
-            }
-        }
-
-        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
-            if dataTaskDidReceiveData != nil {
-                dataTaskDidReceiveData!(session, dataTask, data)
-            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
-                delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, willCacheResponse proposedResponse: NSCachedURLResponse, completionHandler: ((NSCachedURLResponse!) -> Void)) {
-            if dataTaskWillCacheResponse != nil {
-                completionHandler(dataTaskWillCacheResponse!(session, dataTask, proposedResponse))
-            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
-                delegate.URLSession(session, dataTask: dataTask, willCacheResponse: proposedResponse, completionHandler: completionHandler)
-            } else {
-                completionHandler(proposedResponse)
-            }
-        }
-
-        // MARK: NSURLSessionDownloadDelegate
-
-        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didFinishDownloadingToURL:`.
-        public var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> Void)?
-
-        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:`.
-        public var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)?
-
-        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`.
-        public var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)?
-
-        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
-            if downloadTaskDidFinishDownloadingToURL != nil {
-                downloadTaskDidFinishDownloadingToURL!(session, downloadTask, location)
-            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
-                delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
-            if downloadTaskDidWriteData != nil {
-                downloadTaskDidWriteData!(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
-            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
-                delegate.URLSession(session, downloadTask: downloadTask, didWriteData: bytesWritten, totalBytesWritten: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite)
-            }
-        }
-
-        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
-            if downloadTaskDidResumeAtOffset != nil {
-                downloadTaskDidResumeAtOffset!(session, downloadTask, fileOffset, expectedTotalBytes)
-            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
-                delegate.URLSession(session, downloadTask: downloadTask, didResumeAtOffset: fileOffset, expectedTotalBytes: expectedTotalBytes)
-            }
-        }
-
-        // MARK: NSObject
-
-        public override func respondsToSelector(selector: Selector) -> Bool {
-            switch selector {
-            case "URLSession:didBecomeInvalidWithError:":
-                return (sessionDidBecomeInvalidWithError != nil)
-            case "URLSession:didReceiveChallenge:completionHandler:":
-                return (sessionDidReceiveChallenge != nil)
-            case "URLSessionDidFinishEventsForBackgroundURLSession:":
-                return (sessionDidFinishEventsForBackgroundURLSession != nil)
-            case "URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:":
-                return (taskWillPerformHTTPRedirection != nil)
-            case "URLSession:dataTask:didReceiveResponse:completionHandler:":
-                return (dataTaskDidReceiveResponse != nil)
-            case "URLSession:dataTask:willCacheResponse:completionHandler:":
-                return (dataTaskWillCacheResponse != nil)
-            default:
-                return self.dynamicType.instancesRespondToSelector(selector)
-            }
-        }
-    }
-}
-
-// MARK: -
-
 /**
     Responsible for sending a request and receiving the response and associated data from the server, as well as managing its underlying `NSURLSessionTask`.
 */

+ 379 - 0
Source/Manager.swift

@@ -0,0 +1,379 @@
+// Alamofire.swift
+//
+// Copyright (c) 2014–2015 Alamofire Software Foundation (http://alamofire.org/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+import Foundation
+
+/**
+    Responsible for creating and managing `Request` objects, as well as their underlying `NSURLSession`.
+*/
+public class Manager {
+    
+    /**
+        A shared instance of `Manager`, used by top-level Alamofire request methods, and suitable for use directly for any ad hoc requests.
+    */
+    public static let sharedInstance: Manager = {
+        let configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
+        configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
+        
+        return Manager(configuration: configuration)
+    }()
+    
+    /**
+        Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
+    
+        :returns: The default header values.
+    */
+    public static let defaultHTTPHeaders: [String: String] = {
+        // Accept-Encoding HTTP Header; see http://tools.ietf.org/html/rfc7230#section-4.2.3
+        let acceptEncoding: String = "gzip;q=1.0,compress;q=0.5"
+        
+        // Accept-Language HTTP Header; see http://tools.ietf.org/html/rfc7231#section-5.3.5
+        let acceptLanguage: String = {
+            var components: [String] = []
+            for (index, languageCode) in enumerate(NSLocale.preferredLanguages() as! [String]) {
+                let q = 1.0 - (Double(index) * 0.1)
+                components.append("\(languageCode);q=\(q)")
+                if q <= 0.5 {
+                    break
+                }
+            }
+            
+            return join(",", components)
+        }()
+        
+        // User-Agent Header; see http://tools.ietf.org/html/rfc7231#section-5.5.3
+        let userAgent: String = {
+            if let info = NSBundle.mainBundle().infoDictionary {
+                let executable: AnyObject = info[kCFBundleExecutableKey] ?? "Unknown"
+                let bundle: AnyObject = info[kCFBundleIdentifierKey] ?? "Unknown"
+                let version: AnyObject = info[kCFBundleVersionKey] ?? "Unknown"
+                let os: AnyObject = NSProcessInfo.processInfo().operatingSystemVersionString ?? "Unknown"
+                
+                var mutableUserAgent = NSMutableString(string: "\(executable)/\(bundle) (\(version); OS \(os))") as CFMutableString
+                let transform = NSString(string: "Any-Latin; Latin-ASCII; [:^ASCII:] Remove") as CFString
+                if CFStringTransform(mutableUserAgent, nil, transform, 0) == 1 {
+                    return mutableUserAgent as NSString as! String
+                }
+            }
+            
+            return "Alamofire"
+        }()
+        
+        return ["Accept-Encoding": acceptEncoding,
+            "Accept-Language": acceptLanguage,
+            "User-Agent": userAgent]
+    }()
+    
+    private let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)
+    
+    /// The underlying session.
+    public let session: NSURLSession
+    
+    /// The session delegate handling all the task and session delegate callbacks.
+    public let delegate: SessionDelegate
+    
+    /// Whether to start requests immediately after being constructed. `true` by default.
+    public var startRequestsImmediately: Bool = true
+    
+    /// The background completion handler closure provided by the UIApplicationDelegate `application:handleEventsForBackgroundURLSession:completionHandler:` method. By setting the background completion handler, the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` closure implementation will automatically call the handler. If you need to handle your own events before the handler is called, then you need to override the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` and manually call the handler when finished. `nil` by default.
+    public var backgroundCompletionHandler: (() -> Void)?
+    
+    /**
+        :param: configuration The configuration used to construct the managed session.
+    */
+    required public init(configuration: NSURLSessionConfiguration? = nil) {
+        self.delegate = SessionDelegate()
+        self.session = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
+        
+        self.delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
+            if let strongSelf = self {
+                strongSelf.backgroundCompletionHandler?()
+            }
+        }
+    }
+    
+    deinit {
+        self.session.invalidateAndCancel()
+    }
+    
+    // MARK: -
+    
+    /**
+        Creates a request for the specified method, URL string, parameters, and parameter encoding.
+    
+        :param: method The HTTP method.
+        :param: URLString The URL string.
+        :param: parameters The parameters. `nil` by default.
+        :param: encoding The parameter encoding. `.URL` by default.
+    
+        :returns: The created request.
+    */
+    public func request(method: Method, _ URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL) -> Request {
+        return request(encoding.encode(URLRequest(method, URLString), parameters: parameters).0)
+    }
+    
+    /**
+        Creates a request for the specified URL request.
+    
+        If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
+    
+        :param: URLRequest The URL request
+    
+        :returns: The created request.
+    */
+    public func request(URLRequest: URLRequestConvertible) -> Request {
+        var dataTask: NSURLSessionDataTask?
+        dispatch_sync(queue) {
+            dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest)
+        }
+        
+        let request = Request(session: session, task: dataTask!)
+        delegate[request.delegate.task] = request.delegate
+        
+        if startRequestsImmediately {
+            request.resume()
+        }
+        
+        return request
+    }
+    
+    /**
+        Responsible for handling all delegate callbacks for the underlying session.
+    */
+    public final class SessionDelegate: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate {
+        private var subdelegates: [Int: Request.TaskDelegate] = [:]
+        private let subdelegateQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT)
+        private subscript(task: NSURLSessionTask) -> Request.TaskDelegate? {
+            get {
+                var subdelegate: Request.TaskDelegate?
+                dispatch_sync(subdelegateQueue) {
+                    subdelegate = self.subdelegates[task.taskIdentifier]
+                }
+                
+                return subdelegate
+            }
+            
+            set {
+                dispatch_barrier_async(subdelegateQueue) {
+                    self.subdelegates[task.taskIdentifier] = newValue
+                }
+            }
+        }
+        
+        // MARK: NSURLSessionDelegate
+        
+        /// NSURLSessionDelegate override closure for `URLSession:didBecomeInvalidWithError:` method.
+        public var sessionDidBecomeInvalidWithError: ((NSURLSession, NSError?) -> Void)?
+        
+        /// NSURLSessionDelegate override closure for `URLSession:didReceiveChallenge:completionHandler:` method.
+        public var sessionDidReceiveChallenge: ((NSURLSession, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential!))?
+        
+        /// NSURLSessionDelegate override closure for `URLSessionDidFinishEventsForBackgroundURLSession:` method.
+        public var sessionDidFinishEventsForBackgroundURLSession: ((NSURLSession) -> Void)?
+        
+        public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
+            sessionDidBecomeInvalidWithError?(session, error)
+        }
+        
+        public func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)) {
+            if sessionDidReceiveChallenge != nil {
+                completionHandler(sessionDidReceiveChallenge!(session, challenge))
+            } else {
+                completionHandler(.PerformDefaultHandling, nil)
+            }
+        }
+        
+        public func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
+            sessionDidFinishEventsForBackgroundURLSession?(session)
+        }
+        
+        // MARK: NSURLSessionTaskDelegate
+        
+        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:`.
+        public var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> (NSURLRequest!))?
+        
+        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didReceiveChallenge:completionHandler:`.
+        public var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential!))?
+        
+        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:session:task:needNewBodyStream:`.
+        public var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> (NSInputStream!))?
+        
+        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`.
+        public var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)?
+        
+        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didCompleteWithError:`.
+        public var taskDidComplete: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)?
+        
+        public func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: ((NSURLRequest!) -> Void)) {
+            var redirectRequest: NSURLRequest? = request
+            
+            if taskWillPerformHTTPRedirection != nil {
+                redirectRequest = taskWillPerformHTTPRedirection!(session, task, response, request)
+            }
+            
+            completionHandler(redirectRequest)
+        }
+        
+        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void)) {
+            if taskDidReceiveChallenge != nil {
+                completionHandler(taskDidReceiveChallenge!(session, task, challenge))
+            } else if let delegate = self[task] {
+                delegate.URLSession(session, task: task, didReceiveChallenge: challenge, completionHandler: completionHandler)
+            } else {
+                URLSession(session, didReceiveChallenge: challenge, completionHandler: completionHandler)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, task: NSURLSessionTask, needNewBodyStream completionHandler: ((NSInputStream!) -> Void)) {
+            if taskNeedNewBodyStream != nil {
+                completionHandler(taskNeedNewBodyStream!(session, task))
+            } else if let delegate = self[task] {
+                delegate.URLSession(session, task: task, needNewBodyStream: completionHandler)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
+            if taskDidSendBodyData != nil {
+                taskDidSendBodyData!(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
+            } else if let delegate = self[task] as? Request.UploadTaskDelegate {
+                delegate.URLSession(session, task: task, didSendBodyData: bytesSent, totalBytesSent: totalBytesSent, totalBytesExpectedToSend: totalBytesExpectedToSend)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
+            if taskDidComplete != nil {
+                taskDidComplete!(session, task, error)
+            } else if let delegate = self[task] {
+                delegate.URLSession(session, task: task, didCompleteWithError: error)
+                
+                self[task] = nil
+            }
+        }
+        
+        // MARK: NSURLSessionDataDelegate
+        
+        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveResponse:completionHandler:`.
+        public var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> (NSURLSessionResponseDisposition))?
+        
+        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didBecomeDownloadTask:`.
+        public var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)?
+        
+        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveData:`.
+        public var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)?
+        
+        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:willCacheResponse:completionHandler:`.
+        public var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> (NSCachedURLResponse!))?
+        
+        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: ((NSURLSessionResponseDisposition) -> Void)) {
+            var disposition: NSURLSessionResponseDisposition = .Allow
+            
+            if dataTaskDidReceiveResponse != nil {
+                disposition = dataTaskDidReceiveResponse!(session, dataTask, response)
+            }
+            
+            completionHandler(disposition)
+        }
+        
+        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask) {
+            if dataTaskDidBecomeDownloadTask != nil {
+                dataTaskDidBecomeDownloadTask!(session, dataTask, downloadTask)
+            } else {
+                let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
+                self[downloadTask] = downloadDelegate
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
+            if dataTaskDidReceiveData != nil {
+                dataTaskDidReceiveData!(session, dataTask, data)
+            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
+                delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, willCacheResponse proposedResponse: NSCachedURLResponse, completionHandler: ((NSCachedURLResponse!) -> Void)) {
+            if dataTaskWillCacheResponse != nil {
+                completionHandler(dataTaskWillCacheResponse!(session, dataTask, proposedResponse))
+            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
+                delegate.URLSession(session, dataTask: dataTask, willCacheResponse: proposedResponse, completionHandler: completionHandler)
+            } else {
+                completionHandler(proposedResponse)
+            }
+        }
+        
+        // MARK: NSURLSessionDownloadDelegate
+        
+        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didFinishDownloadingToURL:`.
+        public var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> Void)?
+        
+        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:`.
+        public var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)?
+        
+        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`.
+        public var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)?
+        
+        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
+            if downloadTaskDidFinishDownloadingToURL != nil {
+                downloadTaskDidFinishDownloadingToURL!(session, downloadTask, location)
+            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+                delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
+            if downloadTaskDidWriteData != nil {
+                downloadTaskDidWriteData!(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
+            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+                delegate.URLSession(session, downloadTask: downloadTask, didWriteData: bytesWritten, totalBytesWritten: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite)
+            }
+        }
+        
+        public func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
+            if downloadTaskDidResumeAtOffset != nil {
+                downloadTaskDidResumeAtOffset!(session, downloadTask, fileOffset, expectedTotalBytes)
+            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
+                delegate.URLSession(session, downloadTask: downloadTask, didResumeAtOffset: fileOffset, expectedTotalBytes: expectedTotalBytes)
+            }
+        }
+        
+        // MARK: NSObject
+        
+        public override func respondsToSelector(selector: Selector) -> Bool {
+            switch selector {
+            case "URLSession:didBecomeInvalidWithError:":
+                return (sessionDidBecomeInvalidWithError != nil)
+            case "URLSession:didReceiveChallenge:completionHandler:":
+                return (sessionDidReceiveChallenge != nil)
+            case "URLSessionDidFinishEventsForBackgroundURLSession:":
+                return (sessionDidFinishEventsForBackgroundURLSession != nil)
+            case "URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:":
+                return (taskWillPerformHTTPRedirection != nil)
+            case "URLSession:dataTask:didReceiveResponse:completionHandler:":
+                return (dataTaskDidReceiveResponse != nil)
+            case "URLSession:dataTask:willCacheResponse:completionHandler:":
+                return (dataTaskWillCacheResponse != nil)
+            default:
+                return self.dynamicType.instancesRespondToSelector(selector)
+            }
+        }
+    }
+}