123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 |
- // Manager.swift
- //
- // Copyright (c) 2014–2016 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 {
- // MARK: - Properties
- /**
- 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.defaultSessionConfiguration()
- configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders
- return Manager(configuration: configuration)
- }()
- /**
- Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
- */
- public static let defaultHTTPHeaders: [String: String] = {
- // Accept-Encoding HTTP Header; see https://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 https://tools.ietf.org/html/rfc7231#section-5.3.5
- let acceptLanguage = NSLocale.preferredLanguages().prefix(6).enumerate().map { index, languageCode in
- let quality = 1.0 - (Double(index) * 0.1)
- return "\(languageCode);q=\(quality)"
- }.joinWithSeparator(", ")
- // User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
- let userAgent: String = {
- if let info = NSBundle.mainBundle().infoDictionary {
- let executable: AnyObject = info[kCFBundleExecutableKey as String] ?? "Unknown"
- let bundle: AnyObject = info[kCFBundleIdentifierKey as String] ?? "Unknown"
- let version: AnyObject = info[kCFBundleVersionKey as String] ?? "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, UnsafeMutablePointer<CFRange>(nil), transform, false) {
- return mutableUserAgent as String
- }
- }
- return "Alamofire"
- }()
- return [
- "Accept-Encoding": acceptEncoding,
- "Accept-Language": acceptLanguage,
- "User-Agent": userAgent
- ]
- }()
- 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)?
- // MARK: - Lifecycle
- /**
- Initializes the `Manager` instance with the specified configuration, delegate and server trust policy.
- - parameter configuration: The configuration used to construct the managed session.
- `NSURLSessionConfiguration.defaultSessionConfiguration()` by default.
- - parameter delegate: The delegate used when initializing the session. `SessionDelegate()` by
- default.
- - parameter serverTrustPolicyManager: The server trust policy manager to use for evaluating all server trust
- challenges. `nil` by default.
- - returns: The new `Manager` instance.
- */
- public init(
- configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration(),
- delegate: SessionDelegate = SessionDelegate(),
- serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
- {
- self.delegate = delegate
- self.session = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
- commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
- }
- /**
- Initializes the `Manager` instance with the specified session, delegate and server trust policy.
- - parameter session: The URL session.
- - parameter delegate: The delegate of the URL session. Must equal the URL session's delegate.
- - parameter serverTrustPolicyManager: The server trust policy manager to use for evaluating all server trust
- challenges. `nil` by default.
- - returns: The new `Manager` instance if the URL session's delegate matches the delegate parameter.
- */
- public init?(
- session: NSURLSession,
- delegate: SessionDelegate,
- serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
- {
- self.delegate = delegate
- self.session = session
- guard delegate === session.delegate else { return nil }
- commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
- }
- private func commonInit(serverTrustPolicyManager serverTrustPolicyManager: ServerTrustPolicyManager?) {
- session.serverTrustPolicyManager = serverTrustPolicyManager
- delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
- guard let strongSelf = self else { return }
- dispatch_async(dispatch_get_main_queue()) { strongSelf.backgroundCompletionHandler?() }
- }
- }
- deinit {
- session.invalidateAndCancel()
- }
- // MARK: - Request
- /**
- Creates a request for the specified method, URL string, parameters, parameter encoding and headers.
- - parameter method: The HTTP method.
- - parameter URLString: The URL string.
- - parameter parameters: The parameters. `nil` by default.
- - parameter encoding: The parameter encoding. `.URL` by default.
- - parameter headers: The HTTP headers. `nil` by default.
- - returns: The created request.
- */
- public func request(
- method: Method,
- _ URLString: URLStringConvertible,
- parameters: [String: AnyObject]? = nil,
- encoding: ParameterEncoding = .URL,
- headers: [String: String]? = nil)
- -> Request
- {
- let mutableURLRequest = URLRequest(method, URLString, headers: headers)
- let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
- return request(encodedURLRequest)
- }
- /**
- Creates a request for the specified URL request.
- If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
- - parameter 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
- }
- // MARK: - SessionDelegate
- /**
- 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)
- 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 }
- }
- }
- /**
- Initializes the `SessionDelegate` instance.
- - returns: The new `SessionDelegate` instance.
- */
- public override init() {
- super.init()
- }
- // MARK: - NSURLSessionDelegate
- // MARK: Override Closures
- /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didBecomeInvalidWithError:`.
- public var sessionDidBecomeInvalidWithError: ((NSURLSession, NSError?) -> Void)?
- /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didReceiveChallenge:completionHandler:`.
- public var sessionDidReceiveChallenge: ((NSURLSession, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?
- /// Overrides default behavior for NSURLSessionDelegate method `URLSessionDidFinishEventsForBackgroundURLSession:`.
- public var sessionDidFinishEventsForBackgroundURLSession: ((NSURLSession) -> Void)?
- // MARK: Delegate Methods
- /**
- Tells the delegate that the session has been invalidated.
- - parameter session: The session object that was invalidated.
- - parameter error: The error that caused invalidation, or nil if the invalidation was explicit.
- */
- public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
- sessionDidBecomeInvalidWithError?(session, error)
- }
- /**
- Requests credentials from the delegate in response to a session-level authentication request from the remote server.
- - parameter session: The session containing the task that requested authentication.
- - parameter challenge: An object that contains the request for authentication.
- - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
- */
- public func URLSession(
- session: NSURLSession,
- didReceiveChallenge challenge: NSURLAuthenticationChallenge,
- completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
- {
- var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
- var credential: NSURLCredential?
- if let sessionDidReceiveChallenge = sessionDidReceiveChallenge {
- (disposition, credential) = sessionDidReceiveChallenge(session, challenge)
- } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
- let host = challenge.protectionSpace.host
- if let
- serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host),
- serverTrust = challenge.protectionSpace.serverTrust
- {
- if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
- disposition = .UseCredential
- credential = NSURLCredential(forTrust: serverTrust)
- } else {
- disposition = .CancelAuthenticationChallenge
- }
- }
- }
- completionHandler(disposition, credential)
- }
- /**
- Tells the delegate that all messages enqueued for a session have been delivered.
- - parameter session: The session that no longer has any outstanding requests.
- */
- public func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
- sessionDidFinishEventsForBackgroundURLSession?(session)
- }
- // MARK: - NSURLSessionTaskDelegate
- // MARK: Override Closures
- /// 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)?
- // MARK: Delegate Methods
- /**
- Tells the delegate that the remote server requested an HTTP redirect.
- - parameter session: The session containing the task whose request resulted in a redirect.
- - parameter task: The task whose request resulted in a redirect.
- - parameter response: An object containing the server’s response to the original request.
- - parameter request: A URL request object filled out with the new location.
- - parameter completionHandler: A closure that your handler should call with either the value of the request
- parameter, a modified URL request object, or NULL to refuse the redirect and
- return the body of the redirect response.
- */
- public func URLSession(
- session: NSURLSession,
- task: NSURLSessionTask,
- willPerformHTTPRedirection response: NSHTTPURLResponse,
- newRequest request: NSURLRequest,
- completionHandler: ((NSURLRequest?) -> Void))
- {
- var redirectRequest: NSURLRequest? = request
- if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection {
- redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request)
- }
- completionHandler(redirectRequest)
- }
- /**
- Requests credentials from the delegate in response to an authentication request from the remote server.
- - parameter session: The session containing the task whose request requires authentication.
- - parameter task: The task whose request requires authentication.
- - parameter challenge: An object that contains the request for authentication.
- - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
- */
- public func URLSession(
- session: NSURLSession,
- task: NSURLSessionTask,
- didReceiveChallenge challenge: NSURLAuthenticationChallenge,
- completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
- {
- if let taskDidReceiveChallenge = taskDidReceiveChallenge {
- 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)
- }
- }
- /**
- Tells the delegate when a task requires a new request body stream to send to the remote server.
- - parameter session: The session containing the task that needs a new body stream.
- - parameter task: The task that needs a new body stream.
- - parameter completionHandler: A completion handler that your delegate method should call with the new body stream.
- */
- public func URLSession(
- session: NSURLSession,
- task: NSURLSessionTask,
- needNewBodyStream completionHandler: ((NSInputStream?) -> Void))
- {
- if let taskNeedNewBodyStream = taskNeedNewBodyStream {
- completionHandler(taskNeedNewBodyStream(session, task))
- } else if let delegate = self[task] {
- delegate.URLSession(session, task: task, needNewBodyStream: completionHandler)
- }
- }
- /**
- Periodically informs the delegate of the progress of sending body content to the server.
- - parameter session: The session containing the data task.
- - parameter task: The data task.
- - parameter bytesSent: The number of bytes sent since the last time this delegate method was called.
- - parameter totalBytesSent: The total number of bytes sent so far.
- - parameter totalBytesExpectedToSend: The expected length of the body data.
- */
- public func URLSession(
- session: NSURLSession,
- task: NSURLSessionTask,
- didSendBodyData bytesSent: Int64,
- totalBytesSent: Int64,
- totalBytesExpectedToSend: Int64)
- {
- if let taskDidSendBodyData = taskDidSendBodyData {
- 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
- )
- }
- }
- /**
- Tells the delegate that the task finished transferring data.
- - parameter session: The session containing the task whose request finished transferring data.
- - parameter task: The task whose request finished transferring data.
- - parameter error: If an error occurred, an error object indicating how the transfer failed, otherwise nil.
- */
- public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
- if let taskDidComplete = taskDidComplete {
- taskDidComplete(session, task, error)
- } else if let delegate = self[task] {
- delegate.URLSession(session, task: task, didCompleteWithError: error)
- }
- NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidComplete, object: task)
- self[task] = nil
- }
- // MARK: - NSURLSessionDataDelegate
- // MARK: Override Closures
- /// 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!)?
- // MARK: Delegate Methods
- /**
- Tells the delegate that the data task received the initial reply (headers) from the server.
- - parameter session: The session containing the data task that received an initial reply.
- - parameter dataTask: The data task that received an initial reply.
- - parameter response: A URL response object populated with headers.
- - parameter completionHandler: A completion handler that your code calls to continue the transfer, passing a
- constant to indicate whether the transfer should continue as a data task or
- should become a download task.
- */
- public func URLSession(
- session: NSURLSession,
- dataTask: NSURLSessionDataTask,
- didReceiveResponse response: NSURLResponse,
- completionHandler: ((NSURLSessionResponseDisposition) -> Void))
- {
- var disposition: NSURLSessionResponseDisposition = .Allow
- if let dataTaskDidReceiveResponse = dataTaskDidReceiveResponse {
- disposition = dataTaskDidReceiveResponse(session, dataTask, response)
- }
- completionHandler(disposition)
- }
- /**
- Tells the delegate that the data task was changed to a download task.
- - parameter session: The session containing the task that was replaced by a download task.
- - parameter dataTask: The data task that was replaced by a download task.
- - parameter downloadTask: The new download task that replaced the data task.
- */
- public func URLSession(
- session: NSURLSession,
- dataTask: NSURLSessionDataTask,
- didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask)
- {
- if let dataTaskDidBecomeDownloadTask = dataTaskDidBecomeDownloadTask {
- dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask)
- } else {
- let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
- self[downloadTask] = downloadDelegate
- }
- }
- /**
- Tells the delegate that the data task has received some of the expected data.
- - parameter session: The session containing the data task that provided data.
- - parameter dataTask: The data task that provided data.
- - parameter data: A data object containing the transferred data.
- */
- public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
- if let dataTaskDidReceiveData = dataTaskDidReceiveData {
- dataTaskDidReceiveData(session, dataTask, data)
- } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
- delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
- }
- }
- /**
- Asks the delegate whether the data (or upload) task should store the response in the cache.
- - parameter session: The session containing the data (or upload) task.
- - parameter dataTask: The data (or upload) task.
- - parameter proposedResponse: The default caching behavior. This behavior is determined based on the current
- caching policy and the values of certain received headers, such as the Pragma
- and Cache-Control headers.
- - parameter completionHandler: A block that your handler must call, providing either the original proposed
- response, a modified version of that response, or NULL to prevent caching the
- response. If your delegate implements this method, it must call this completion
- handler; otherwise, your app leaks memory.
- */
- public func URLSession(
- session: NSURLSession,
- dataTask: NSURLSessionDataTask,
- willCacheResponse proposedResponse: NSCachedURLResponse,
- completionHandler: ((NSCachedURLResponse?) -> Void))
- {
- if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
- 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
- // MARK: Override Closures
- /// 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)?
- // MARK: Delegate Methods
- /**
- Tells the delegate that a download task has finished downloading.
- - parameter session: The session containing the download task that finished.
- - parameter downloadTask: The download task that finished.
- - parameter location: A file URL for the temporary file. Because the file is temporary, you must either
- open the file for reading or move it to a permanent location in your app’s sandbox
- container directory before returning from this delegate method.
- */
- public func URLSession(
- session: NSURLSession,
- downloadTask: NSURLSessionDownloadTask,
- didFinishDownloadingToURL location: NSURL)
- {
- if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
- downloadTaskDidFinishDownloadingToURL(session, downloadTask, location)
- } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
- delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
- }
- }
- /**
- Periodically informs the delegate about the download’s progress.
- - parameter session: The session containing the download task.
- - parameter downloadTask: The download task.
- - parameter bytesWritten: The number of bytes transferred since the last time this delegate
- method was called.
- - parameter totalBytesWritten: The total number of bytes transferred so far.
- - parameter totalBytesExpectedToWrite: The expected length of the file, as provided by the Content-Length
- header. If this header was not provided, the value is
- `NSURLSessionTransferSizeUnknown`.
- */
- public func URLSession(
- session: NSURLSession,
- downloadTask: NSURLSessionDownloadTask,
- didWriteData bytesWritten: Int64,
- totalBytesWritten: Int64,
- totalBytesExpectedToWrite: Int64)
- {
- if let downloadTaskDidWriteData = downloadTaskDidWriteData {
- 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
- )
- }
- }
- /**
- Tells the delegate that the download task has resumed downloading.
- - parameter session: The session containing the download task that finished.
- - parameter downloadTask: The download task that resumed. See explanation in the discussion.
- - parameter fileOffset: If the file's cache policy or last modified date prevents reuse of the
- existing content, then this value is zero. Otherwise, this value is an
- integer representing the number of bytes on disk that do not need to be
- retrieved again.
- - parameter expectedTotalBytes: The expected length of the file, as provided by the Content-Length header.
- If this header was not provided, the value is NSURLSessionTransferSizeUnknown.
- */
- public func URLSession(
- session: NSURLSession,
- downloadTask: NSURLSessionDownloadTask,
- didResumeAtOffset fileOffset: Int64,
- expectedTotalBytes: Int64)
- {
- if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
- downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
- } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
- delegate.URLSession(
- session,
- downloadTask: downloadTask,
- didResumeAtOffset: fileOffset,
- expectedTotalBytes: expectedTotalBytes
- )
- }
- }
- // MARK: - NSURLSessionStreamDelegate
- var _streamTaskReadClosed: Any?
- var _streamTaskWriteClosed: Any?
- var _streamTaskBetterRouteDiscovered: Any?
- var _streamTaskDidBecomeInputStream: Any?
- // 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
- default:
- return self.dynamicType.instancesRespondToSelector(selector)
- }
- }
- }
- }
|