Jelajahi Sumber

[PR #1723] Refactored download completion to not crash on nil response.

Jon Shier 9 tahun lalu
induk
melakukan
cadf4fbb04
2 mengubah file dengan 49 tambahan dan 20 penghapusan
  1. 21 20
      Source/TaskDelegate.swift
  2. 28 0
      Tests/DownloadTests.swift

+ 21 - 20
Source/TaskDelegate.swift

@@ -331,29 +331,30 @@ class DownloadTaskDelegate: TaskDelegate, URLSessionDownloadDelegate {
     {
         temporaryURL = location
 
-        if let destination = destination {
-            let result = destination(location, downloadTask.response as! HTTPURLResponse)
-            let destination = result.destinationURL
-            let options = result.options
-
-            do {
-                destinationURL = destination
-
-                if options.contains(.removePreviousFile) {
-                    if FileManager.default.fileExists(atPath: destination.path) {
-                        try FileManager.default.removeItem(at: destination)
-                    }
-                }
+        guard
+            let destination = destination,
+            let response = downloadTask.response as? HTTPURLResponse
+        else { return }
 
-                if options.contains(.createIntermediateDirectories) {
-                    let directory = destination.deletingLastPathComponent()
-                    try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
-                }
+        let result = destination(location, response)
+        let destinationURL = result.destinationURL
+        let options = result.options
+
+        self.destinationURL = destinationURL
 
-                try FileManager.default.moveItem(at: location, to: destination)
-            } catch {
-                self.error = error
+        do {
+            if options.contains(.removePreviousFile), FileManager.default.fileExists(atPath: destinationURL.path) {
+                try FileManager.default.removeItem(at: destinationURL)
             }
+
+            if options.contains(.createIntermediateDirectories) {
+                let directory = destinationURL.deletingLastPathComponent()
+                try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
+            }
+
+            try FileManager.default.moveItem(at: location, to: destinationURL)
+        } catch {
+            self.error = error
         }
     }
 

+ 28 - 0
Tests/DownloadTests.swift

@@ -102,6 +102,34 @@ class DownloadResponseTestCase: BaseTestCase {
         }
     }
 
+    func testCancelledDownloadRequest() {
+        // Given
+        let fileURL = randomCachesFileURL
+        let numberOfLines = 100
+        let urlString = "https://httpbin.org/stream/\(numberOfLines)"
+        let destination: DownloadRequest.DownloadFileDestination = { _, _ in (fileURL, []) }
+
+        let expectation = self.expectation(description: "Cancelled download request should not download data to file")
+        var response: DefaultDownloadResponse?
+
+        // When
+        Alamofire.download(urlString, to: destination)
+            .response { resp in
+                response = resp
+                expectation.fulfill()
+            }
+            .cancel()
+
+        waitForExpectations(timeout: timeout, handler: nil)
+
+        // Then
+        XCTAssertNotNil(response?.request)
+        XCTAssertNil(response?.response)
+        XCTAssertNil(response?.destinationURL)
+        XCTAssertNil(response?.resumeData)
+        XCTAssertNotNil(response?.error)
+    }
+
     func testDownloadRequestWithProgress() {
         // Given
         let randomBytes = 4 * 1024 * 1024