From a876780e3c952f64bf7100f09dd654bb5deb91dd Mon Sep 17 00:00:00 2001 From: Balazs Perlaki-Horvath Date: Thu, 1 Aug 2024 22:47:24 +0200 Subject: [PATCH] WebKitHandler concurency fix --- Model/Utilities/WebKitHandler.swift | 35 +++++++++++++---------------- ViewModel/BrowserViewModel.swift | 10 +++++---- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Model/Utilities/WebKitHandler.swift b/Model/Utilities/WebKitHandler.swift index 7becdb4d..3311ea08 100644 --- a/Model/Utilities/WebKitHandler.swift +++ b/Model/Utilities/WebKitHandler.swift @@ -25,50 +25,45 @@ import WebKit /// until WebKit behavior is changed. final class KiwixURLSchemeHandler: NSObject, WKURLSchemeHandler { static let KiwixScheme = "kiwix" - private let inSync = InSync(label: "org.kiwix.url.scheme.sync") - private var startedTasks: [Int: Bool] = [:] + @MainActor private var startedTasks: [Int: Bool] = [:] // MARK: Life cycle - private func startFor(_ hashValue: Int) async { - await withCheckedContinuation { continuation in - inSync.execute { - self.startedTasks[hashValue] = true - continuation.resume() - } - } + @MainActor + private func startFor(_ hashValue: Int) { + startedTasks[hashValue] = true } + @MainActor private func isStartedFor(_ hashValue: Int) -> Bool { - return inSync.read { - self.startedTasks[hashValue] != nil - } + startedTasks[hashValue] != nil } + @MainActor private func stopFor(_ hashValue: Int) { - inSync.execute { - self.startedTasks.removeValue(forKey: hashValue) - } + startedTasks.removeValue(forKey: hashValue) } + @MainActor private func stopAll() { - inSync.execute { - self.startedTasks.removeAll() - } + startedTasks.removeAll() } + @MainActor func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) { stopFor(urlSchemeTask.hash) } + @MainActor func didFailProvisionalNavigation() { stopAll() } + @MainActor func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) { guard isStartedFor(urlSchemeTask.hash) == false else { return } - Task { - await startFor(urlSchemeTask.hash) + startFor(urlSchemeTask.hash) + Task { @MainActor in await handle(task: urlSchemeTask) } } diff --git a/ViewModel/BrowserViewModel.swift b/ViewModel/BrowserViewModel.swift index b4ba6727..eceb170c 100644 --- a/ViewModel/BrowserViewModel.swift +++ b/ViewModel/BrowserViewModel.swift @@ -397,10 +397,12 @@ final class BrowserViewModel: NSObject, ObservableObject, withError error: Error ) { let error = error as NSError - webView.stopLoading() - (webView.configuration - .urlSchemeHandler(forURLScheme: KiwixURLSchemeHandler.KiwixScheme) as? KiwixURLSchemeHandler)? - .didFailProvisionalNavigation() + Task { @MainActor in + webView.stopLoading() + (webView.configuration + .urlSchemeHandler(forURLScheme: KiwixURLSchemeHandler.KiwixScheme) as? KiwixURLSchemeHandler)? + .didFailProvisionalNavigation() + } guard error.code != NSURLErrorCancelled else { return } guard canShowMimeType else { guard let kiwixURL = error.userInfo[NSURLErrorFailingURLErrorKey] as? URL else {