From d70c5cc2def742c9f5fb52b9553b426362f1c4f92df42ab62f1aae58eeb2b8c2 Mon Sep 17 00:00:00 2001 From: Yuvomi Mobile Contributors Date: Wed, 21 Oct 2026 07:27:34 +0200 Subject: [PATCH] fix(ios): bind export cancellation to the originating download Ignore late picker callbacks that no longer match the active download. Add an Apple-platform regression; Swift formatting, parsing and seven portable policy tests pass locally, but the new WKWebView regression requires Xcode and has not run here. --- ios/Sources/BrowserModel.swift | 3 ++- ios/Sources/ContentView.swift | 2 +- ios/Tests/BrowserModelTests.swift | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ios/Sources/BrowserModel.swift b/ios/Sources/BrowserModel.swift index 4afb665..79075c7 100644 --- a/ios/Sources/BrowserModel.swift +++ b/ios/Sources/BrowserModel.swift @@ -103,7 +103,8 @@ final class BrowserModel: NSObject, ObservableObject, WKNavigationDelegate, WKUI authentication = WebDestination(url: url) } - func removeDownload() { + func removeDownload(expected: URL? = nil) { + if let expected, download?.url != expected, downloadLocation != expected { return } download = nil if let location = downloadLocation { try? FileManager.default.removeItem(at: location.deletingLastPathComponent()) diff --git a/ios/Sources/ContentView.swift b/ios/Sources/ContentView.swift index d7c47db..1b1abae 100644 --- a/ios/Sources/ContentView.swift +++ b/ios/Sources/ContentView.swift @@ -155,7 +155,7 @@ struct ContentView: View { AuthenticationView(destination: destination.url, model: browser) } .sheet(item: $browser.download) { file in - ExportView(url: file.url) { browser.removeDownload() } + ExportView(url: file.url) { browser.removeDownload(expected: file.url) } } } diff --git a/ios/Tests/BrowserModelTests.swift b/ios/Tests/BrowserModelTests.swift index 53bf437..23e9d73 100644 --- a/ios/Tests/BrowserModelTests.swift +++ b/ios/Tests/BrowserModelTests.swift @@ -13,6 +13,18 @@ final class BrowserModelTests: XCTestCase { XCTAssertFalse(model.web.isInspectable) } + @MainActor + func testLateExportCancellationDoesNotEraseAnotherServersDownload() { + let model = BrowserModel() + let previous = URL(fileURLWithPath: "/old-selection.txt") + let current = URL(fileURLWithPath: "/new-selection.txt") + model.download = WebDestination(url: current) + model.removeDownload(expected: previous) + XCTAssertEqual(model.download?.url, current) + model.removeDownload(expected: current) + XCTAssertNil(model.download) + } + @MainActor func testServerErasureReplacesHistoryContext() async { let model = BrowserModel()