diff --git a/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKDownloadDelegate.swift b/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKDownloadDelegate.swift index a01fb3559026..e72641b519f0 100644 --- a/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKDownloadDelegate.swift +++ b/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKDownloadDelegate.swift @@ -33,6 +33,12 @@ extension BrowserViewController: WKDownloadDelegate { let temporaryDir = NSTemporaryDirectory() let fileName = temporaryDir + "/" + suggestedFilename let url = URL(fileURLWithPath: fileName) + + // WKDownload will fail with a -3000 error code if the file already exists at the given path + if await AsyncFileManager.default.fileExists(atPath: url.path(percentEncoded: false)) { + try? await AsyncFileManager.default.removeItem(at: url) + } + let pendingDownload = WebKitDownload( fileURL: url, response: response, @@ -70,8 +76,6 @@ extension BrowserViewController: WKDownloadDelegate { return } - downloadQueue.download(downloadInfo, didFinishDownloadingTo: downloadInfo.fileURL) - let response = URLResponse( url: downloadInfo.fileURL, mimeType: downloadInfo.response.mimeType, @@ -80,6 +84,7 @@ extension BrowserViewController: WKDownloadDelegate { ) if downloadInfo.response.mimeType == MIMEType.passbook { + downloadQueue.download(downloadInfo, didFinishDownloadingTo: downloadInfo.fileURL) if let passbookHelper = OpenPassBookHelper( request: nil, response: response, @@ -89,12 +94,26 @@ extension BrowserViewController: WKDownloadDelegate { ) { Task { await passbookHelper.open() + try await AsyncFileManager.default.removeItem(at: downloadInfo.fileURL) } } + return } + // Handle non-passbook downloads the same as HTTPDownload + let filename = downloadInfo.filename + let location = downloadInfo.fileURL + let temporaryLocation = FileManager.default.temporaryDirectory + .appending(component: "\(filename)-\(location.lastPathComponent)") + try? FileManager.default.moveItem(at: location, to: temporaryLocation) Task { - try await AsyncFileManager.default.removeItem(at: downloadInfo.fileURL) + do { + let destination = try await downloadInfo.uniqueDownloadPathForFilename(filename) + try await AsyncFileManager.default.moveItem(at: temporaryLocation, to: destination) + downloadQueue.download(downloadInfo, didFinishDownloadingTo: destination) + } catch { + downloadQueue.download(downloadInfo, didCompleteWithError: error) + } } } diff --git a/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift b/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift index e1f45ddbf77b..6f069c3a7d49 100644 --- a/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift +++ b/ios/brave-ios/Sources/Brave/Frontend/Browser/BrowserViewController/BVC+WKNavigationDelegate.swift @@ -755,13 +755,14 @@ extension BrowserViewController: WKNavigationDelegate { return .download } + if response.mimeType == MIMEType.passbook { + return .download + } + // Check if this response should be handed off to Passbook. if shouldDownloadNavigationResponse { shouldDownloadNavigationResponse = false - - if response.mimeType == MIMEType.passbook { - return .download - } + return .download } // If the content type is not HTML, create a temporary document so it can be downloaded and diff --git a/ios/brave-ios/Sources/Brave/Frontend/Browser/DownloadQueue.swift b/ios/brave-ios/Sources/Brave/Frontend/Browser/DownloadQueue.swift index 058a0e91e02e..ef72b1fc8c2c 100644 --- a/ios/brave-ios/Sources/Brave/Frontend/Browser/DownloadQueue.swift +++ b/ios/brave-ios/Sources/Brave/Frontend/Browser/DownloadQueue.swift @@ -38,7 +38,7 @@ class Download: NSObject { func pause() {} func resume() {} - fileprivate func uniqueDownloadPathForFilename(_ filename: String) async throws -> URL { + func uniqueDownloadPathForFilename(_ filename: String) async throws -> URL { let downloadsPath = try await AsyncFileManager.default.downloadsPath() let basePath = downloadsPath.appending(path: filename) let fileExtension = basePath.pathExtension