0001    // Download.swift
0002    //
0003    // Copyright (c) 2014–2016 Alamofire Software Foundation (http://alamofire.org/)
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    import Foundation
0024    
0025    extension Manager {
0026        private enum Downloadable
Download.swift:31
    private func download(downloadable: Downloadable, destination: Request.DownloadFileDestination) -> Request {
{ 0027 case Request
Download.swift:35
        case .Request(let request):
Download.swift:105
        return download(.Request(URLRequest.URLRequest), destination: destination)
(NSURLRequest) 0028 case ResumeData
Download.swift:39
        case .ResumeData(let resumeData):
Download.swift:123
        return download(.ResumeData(resumeData), destination: destination)
(NSData) 0029 } 0030 0031 private func download
Download.swift:105
        return download(.Request(URLRequest.URLRequest), destination: destination)
Download.swift:123
        return download(.ResumeData(resumeData), destination: destination)
(downloadable: Downloadable, destination: Request.DownloadFileDestination) -> Request { 0032 var downloadTask: NSURLSessionDownloadTask! 0033 0034 switch downloadable { 0035 case .Request(let request): 0036 dispatch_sync(queue) { 0037 downloadTask = self.session.downloadTaskWithRequest(request) 0038 } 0039 case .ResumeData(let resumeData): 0040 dispatch_sync(queue) { 0041 downloadTask = self.session.downloadTaskWithResumeData(resumeData) 0042 } 0043 } 0044 0045 let request = Request(session: session, task: downloadTask) 0046 0047 if let downloadDelegate = request.delegate as? Request.DownloadTaskDelegate { 0048 downloadDelegate.downloadTaskDidFinishDownloadingToURL = { session, downloadTask, URL in 0049 return destination(URL, downloadTask.response as! NSHTTPURLResponse) 0050 } 0051 } 0052 0053 delegate[request.delegate.task] = request.delegate 0054 0055 if startRequestsImmediately { 0056 request.resume() 0057 } 0058 0059 return request 0060 } 0061 0062 // MARK: Request 0063 0064 /** 0065 Creates a download request for the specified method, URL string, parameters, parameter encoding, headers 0066 and destination. 0067 0068 If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 0069 0070 - parameter method: The HTTP method. 0071 - parameter URLString: The URL string. 0072 - parameter parameters: The parameters. `nil` by default. 0073 - parameter encoding: The parameter encoding. `.URL` by default. 0074 - parameter headers: The HTTP headers. `nil` by default. 0075 - parameter destination: The closure used to determine the destination of the downloaded file. 0076 0077 - returns: The created download request. 0078 */ 0079 public func download
Alamofire.swift:331
    return Manager.sharedInstance.download(
( 0080 method: Method, 0081 _ URLString: URLStringConvertible, 0082 parameters: [String: AnyObject]? = nil, 0083 encoding: ParameterEncoding = .URL, 0084 headers: [String: String]? = nil, 0085 destination: Request.DownloadFileDestination) 0086 -> Request 0087 { 0088 let mutableURLRequest = URLRequest(method, URLString, headers: headers) 0089 let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0 0090 0091 return download(encodedURLRequest, destination: destination) 0092 } 0093 0094 /** 0095 Creates a request for downloading from the specified URL request. 0096 0097 If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 0098 0099 - parameter URLRequest: The URL request 0100 - parameter destination: The closure used to determine the destination of the downloaded file. 0101 0102 - returns: The created download request. 0103 */ 0104 public func download
Alamofire.swift:350
    return Manager.sharedInstance.download(URLRequest, destination: destination)
Download.swift:91
        return download(encodedURLRequest, destination: destination)
(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request { 0105 return download(.Request(URLRequest.URLRequest), destination: destination) 0106 } 0107 0108 // MARK: Resume Data 0109 0110 /** 0111 Creates a request for downloading from the resume data produced from a previous request cancellation. 0112 0113 If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned. 0114 0115 - parameter resumeData: The resume data. This is an opaque data blob produced by `NSURLSessionDownloadTask` 0116 when a task is cancelled. See `NSURLSession -downloadTaskWithResumeData:` for 0117 additional information. 0118 - parameter destination: The closure used to determine the destination of the downloaded file. 0119 0120 - returns: The created download request. 0121 */ 0122 public func download
Alamofire.swift:367
    return Manager.sharedInstance.download(data, destination: destination)
(resumeData: NSData, destination: Request.DownloadFileDestination) -> Request { 0123 return download(.ResumeData(resumeData), destination: destination) 0124 } 0125 } 0126 0127 // MARK: - 0128 0129 extension Request { 0130 /** 0131 A closure executed once a request has successfully completed in order to determine where to move the temporary 0132 file written to during the download process. The closure takes two arguments: the temporary file URL and the URL 0133 response, and returns a single argument: the file URL where the temporary file should be moved. 0134 */ 0135 public typealias DownloadFileDestination
Alamofire.swift:328
    destination: Request.DownloadFileDestination)
Alamofire.swift:349
public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request {
Alamofire.swift:366
public func download(resumeData data: NSData, destination: Request.DownloadFileDestination) -> Request {
Download.swift:31
    private func download(downloadable: Downloadable, destination: Request.DownloadFileDestination) -> Request {
Download.swift:85
        destination: Request.DownloadFileDestination)
Download.swift:104
    public func download(URLRequest: URLRequestConvertible, destination: Request.DownloadFileDestination) -> Request {
Download.swift:122
    public func download(resumeData: NSData, destination: Request.DownloadFileDestination) -> Request {
Download.swift:149
        -> DownloadFileDestination
= (NSURL, NSHTTPURLResponse) -> NSURL 0136 0137 /** 0138 Creates a download file destination closure which uses the default file manager to move the temporary file to a 0139 file URL in the first available directory with the specified search path directory and search path domain mask. 0140 0141 - parameter directory: The search path directory. `.DocumentDirectory` by default. 0142 - parameter domain: The search path domain mask. `.UserDomainMask` by default. 0143 0144 - returns: A download file destination closure. 0145 */ 0146 public class func suggestedDownloadDestination( 0147 directory directory: NSSearchPathDirectory = .DocumentDirectory, 0148 domain: NSSearchPathDomainMask = .UserDomainMask) 0149 -> DownloadFileDestination 0150 { 0151 return { temporaryURL, response -> NSURL in 0152 let directoryURLs = NSFileManager.defaultManager().URLsForDirectory(directory, inDomains: domain) 0153 0154 if !directoryURLs.isEmpty { 0155 return directoryURLs[0].URLByAppendingPathComponent(response.suggestedFilename!) 0156 } 0157 0158 return temporaryURL 0159 } 0160 } 0161 0162 /// The resume data of the underlying download task if available after a failure. 0163 public var resumeData: NSData? { 0164 var data: NSData? 0165 0166 if let delegate = delegate as? DownloadTaskDelegate { 0167 data = delegate.resumeData 0168 } 0169 0170 return data 0171 } 0172 0173 // MARK: - DownloadTaskDelegate 0174 0175 class DownloadTaskDelegate
Download.swift:47
        if let downloadDelegate = request.delegate as? Request.DownloadTaskDelegate {
Download.swift:166
        if let delegate = delegate as? DownloadTaskDelegate {
Manager.swift:518
                let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
Manager.swift:602
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
Manager.swift:628
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
Manager.swift:659
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
Request.swift:65
            delegate = DownloadTaskDelegate(task: task)
Request.swift:128
        } else if let downloadDelegate = delegate as? DownloadTaskDelegate {
Request.swift:179
            downloadDelegate = delegate as? DownloadTaskDelegate,
Request.swift:322
                        downloadDelegate = self as? DownloadTaskDelegate,
: TaskDelegate, NSURLSessionDownloadDelegate { 0176 var downloadTask
Request.swift:180
            downloadTask = downloadDelegate.downloadTask
: NSURLSessionDownloadTask? { return task as? NSURLSessionDownloadTask } 0177 var downloadProgress
Download.swift:228
                downloadProgress?(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
Request.swift:129
            downloadDelegate.downloadProgress = closure
: ((Int64, Int64, Int64) -> Void)? 0178 0179 var resumeData
Download.swift:167
            data = delegate.resumeData
Download.swift:180
        override var data: NSData? { return resumeData }
Request.swift:183
                downloadDelegate.resumeData = data
Request.swift:326
                        downloadDelegate.resumeData = resumeData
: NSData? 0180 override var data: NSData? { return resumeData } 0181 0182 // MARK: - NSURLSessionDownloadDelegate 0183 0184 // MARK: Override Closures 0185 0186 var downloadTaskDidFinishDownloadingToURL
Download.swift:48
            downloadDelegate.downloadTaskDidFinishDownloadingToURL = { session, downloadTask, URL in
Download.swift:197
            if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> NSURL)? 0187 var downloadTaskDidWriteData
Download.swift:216
            if let downloadTaskDidWriteData = downloadTaskDidWriteData {
: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)? 0188 var downloadTaskDidResumeAtOffset
Download.swift:238
            if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)? 0189 0190 // MARK: Delegate Methods 0191 0192 func URLSession
Manager.swift:603
                delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
( 0193 session: NSURLSession, 0194 downloadTask: NSURLSessionDownloadTask, 0195 didFinishDownloadingToURL location: NSURL) 0196 { 0197 if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL { 0198 do { 0199 let destination = downloadTaskDidFinishDownloadingToURL(session, downloadTask, location) 0200 try NSFileManager.defaultManager().moveItemAtURL(location, toURL: destination) 0201 } catch { 0202 self.error = error as NSError 0203 } 0204 } 0205 } 0206 0207 func URLSession
Manager.swift:629
                delegate.URLSession(
( 0208 session: NSURLSession, 0209 downloadTask: NSURLSessionDownloadTask, 0210 didWriteData bytesWritten: Int64, 0211 totalBytesWritten: Int64, 0212 totalBytesExpectedToWrite: Int64) 0213 { 0214 if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() } 0215 0216 if let downloadTaskDidWriteData = downloadTaskDidWriteData { 0217 downloadTaskDidWriteData( 0218 session, 0219 downloadTask, 0220 bytesWritten, 0221 totalBytesWritten, 0222 totalBytesExpectedToWrite 0223 ) 0224 } else { 0225 progress.totalUnitCount = totalBytesExpectedToWrite 0226 progress.completedUnitCount = totalBytesWritten 0227 0228 downloadProgress?(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) 0229 } 0230 } 0231 0232 func URLSession
Manager.swift:660
                delegate.URLSession(
( 0233 session: NSURLSession, 0234 downloadTask: NSURLSessionDownloadTask, 0235 didResumeAtOffset fileOffset: Int64, 0236 expectedTotalBytes: Int64) 0237 { 0238 if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset { 0239 downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes) 0240 } else { 0241 progress.totalUnitCount = expectedTotalBytes 0242 progress.completedUnitCount = fileOffset 0243 } 0244 } 0245 } 0246 } 0247