Sfoglia il codice sorgente

Merge pull request #595 from Alamofire/feature/download_resume_data

Christian Noon 10 anni fa
parent
commit
70b19822be
3 ha cambiato i file con 144 aggiunte e 7 eliminazioni
  1. 12 1
      Source/Download.swift
  2. 9 1
      Source/Request.swift
  3. 123 5
      Tests/DownloadTests.swift

+ 12 - 1
Source/Download.swift

@@ -134,6 +134,17 @@ extension Request {
         }
     }
 
+    /// The resume data of the underlying download task if available after a failure.
+    public var resumeData: NSData? {
+        var data: NSData?
+
+        if let delegate = self.delegate as? DownloadTaskDelegate {
+            data = delegate.resumeData
+        }
+
+        return data
+    }
+
     // MARK: - DownloadTaskDelegate
 
     class DownloadTaskDelegate: TaskDelegate, NSURLSessionDownloadDelegate {
@@ -141,7 +152,7 @@ extension Request {
         var downloadProgress: ((Int64, Int64, Int64) -> Void)?
 
         var resumeData: NSData?
-        override var data: NSData? { return resumeData }
+        override var data: NSData? { return self.resumeData }
 
         // MARK: - NSURLSessionDownloadDelegate
 

+ 9 - 1
Source/Request.swift

@@ -269,8 +269,16 @@ public class Request {
             if let taskDidCompleteWithError = self.taskDidCompleteWithError {
                 taskDidCompleteWithError(session, task, error)
             } else {
-                if error != nil {
+                if let error = error {
                     self.error = error
+
+                    if let
+                        downloadDelegate = self as? DownloadTaskDelegate,
+                        userInfo = error.userInfo as? [String: AnyObject],
+                        resumeData = userInfo[NSURLSessionDownloadTaskResumeData] as? NSData
+                    {
+                        downloadDelegate.resumeData = resumeData
+                    }
                 }
 
                 self.queue.suspended = false

+ 123 - 5
Tests/DownloadTests.swift

@@ -66,13 +66,9 @@ class DownloadInitializationTestCase: BaseTestCase {
 // MARK: -
 
 class DownloadResponseTestCase: BaseTestCase {
-    // MARK: - Properties
-
     let searchPathDirectory: NSSearchPathDirectory = .CachesDirectory
     let searchPathDomain: NSSearchPathDomainMask = .UserDomainMask
 
-    // MARK: - Tests
-
     func testDownloadRequest() {
         // Given
         let numberOfLines = 100
@@ -181,7 +177,7 @@ class DownloadResponseTestCase: BaseTestCase {
 
         // Then
         XCTAssertNotNil(responseRequest, "response request should not be nil")
-        XCTAssertNotNil(responseResponse, "response response should not be nil")
+        XCTAssertNotNil(responseResponse, "response should not be nil")
         XCTAssertNil(responseData, "response data should be nil")
         XCTAssertNil(responseError, "response error should be nil")
 
@@ -216,3 +212,125 @@ class DownloadResponseTestCase: BaseTestCase {
         XCTAssertNil(removalError, "removal error should be nil")
     }
 }
+
+// MARK: -
+
+class DownloadResumeDataTestCase: BaseTestCase {
+    let URLString = "https://upload.wikimedia.org/wikipedia/commons/6/69/NASA-HS201427a-HubbleUltraDeepField2014-20140603.jpg"
+    let destination: Request.DownloadFileDestination = {
+        let searchPathDirectory: NSSearchPathDirectory = .CachesDirectory
+        let searchPathDomain: NSSearchPathDomainMask = .UserDomainMask
+
+        return Request.suggestedDownloadDestination(directory: searchPathDirectory, domain: searchPathDomain)
+    }()
+
+    func testThatImmediatelyCancelledDownloadDoesNotHaveResumeDataAvailable() {
+        // Given
+        let expectation = expectationWithDescription("Download should be cancelled")
+
+        var request: NSURLRequest?
+        var response: NSHTTPURLResponse?
+        var data: AnyObject?
+        var error: NSError?
+
+        // When
+        let download = Alamofire.download(.GET, self.URLString, destination: self.destination)
+            .response { responseRequest, responseResponse, responseData, responseError in
+                request = responseRequest
+                response = responseResponse
+                data = responseData
+                error = responseError
+
+                expectation.fulfill()
+            }
+
+        download.cancel()
+
+        waitForExpectationsWithTimeout(self.defaultTimeout, handler: nil)
+
+        // Then
+        XCTAssertNotNil(request, "request should not be nil")
+        XCTAssertNil(response, "response should be nil")
+        XCTAssertNil(data, "data should be nil")
+        XCTAssertNotNil(error, "error should not be nil")
+
+        XCTAssertNil(download.resumeData, "resume data should be nil")
+    }
+
+    func testThatCancelledDownloadResponseDataMatchesResumeData() {
+        // Given
+        let expectation = expectationWithDescription("Download should be cancelled")
+
+        var request: NSURLRequest?
+        var response: NSHTTPURLResponse?
+        var data: AnyObject?
+        var error: NSError?
+
+        // When
+        let download = Alamofire.download(.GET, self.URLString, destination: self.destination)
+        download.progress { _, _, _ in
+            download.cancel()
+        }
+        download.response { responseRequest, responseResponse, responseData, responseError in
+            request = responseRequest
+            response = responseResponse
+            data = responseData
+            error = responseError
+
+            expectation.fulfill()
+        }
+
+        waitForExpectationsWithTimeout(self.defaultTimeout, handler: nil)
+
+        // Then
+        XCTAssertNotNil(request, "request should not be nil")
+        XCTAssertNotNil(response, "response should not be nil")
+        XCTAssertNotNil(data, "data should not be nil")
+        XCTAssertNotNil(error, "error should not be nil")
+
+        XCTAssertNotNil(download.resumeData, "resume data should not be nil")
+
+        if let
+            responseData = data as? NSData,
+            resumeData = download.resumeData
+        {
+            XCTAssertEqual(responseData, resumeData, "response data should equal resume data")
+        } else {
+            XCTFail("response data or resume data was unexpectedly nil")
+        }
+    }
+
+    func testThatCancelledDownloadResumeDataIsAvailableWithJSONResponseSerializer() {
+        // Given
+        let expectation = expectationWithDescription("Download should be cancelled")
+
+        var request: NSURLRequest?
+        var response: NSHTTPURLResponse?
+        var JSON: AnyObject?
+        var error: NSError?
+
+        // When
+        let download = Alamofire.download(.GET, self.URLString, destination: self.destination)
+        download.progress { _, _, _ in
+            download.cancel()
+        }
+        download.responseJSON { responseRequest, responseResponse, responseJSON, responseError in
+            request = responseRequest
+            response = responseResponse
+            JSON = responseJSON
+            error = responseError
+
+            expectation.fulfill()
+        }
+
+        waitForExpectationsWithTimeout(self.defaultTimeout, handler: nil)
+
+        // Then
+        XCTAssertNotNil(request, "request should not be nil")
+        XCTAssertNotNil(response, "response should not be nil")
+        XCTAssertNil(JSON, "JSON should be nil")
+        XCTAssertNotNil(error, "error should not be nil")
+
+        XCTAssertNotNil(download.resumeData, "resume data should not be nil")
+    }
+}