I am using the native SwiftUI WebView and WebPage APIs (iOS 26+) and would like to implement file download functionality using the native SwiftUI WebView. However, I have not been able to find any APIs equivalent to WKDownload.
In WKWebView, the WKDownload API can be used to handle downloads. I am looking for a similar API or recommended approach in the native SwiftUI WebView that would allow downloading files.
If anyone has guidance or suggestions on how to implement this, I would appreciate your help.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
In WKWebView, there is the WKUIDelegate method:
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {}
This delegate method provides a callback when a new window (for example, target="_blank") is requested in the web view.
However, in native SwiftUI (iOS 26), WebView / WebPage APIs do not provide an equivalent delegate method to handle new window requests.
As a workaround, I am using the following method:
public func decidePolicy(for action: WebPage.NavigationAction, preferences: inout WebPage.NavigationPreferences) async -> WKNavigationActionPolicy {}
In this method, when action.target == nil, I treat it as a new window request.
My question:
Is relying on action.target == nil in decidePolicy a reliable and future-safe way to detect new window requests in SwiftUI’s WebView, or is there a better or more recommended approach for handling target="_blank" / new window navigation in the SwiftUI WebView APIs?
Code:
public func decidePolicy(for action: WebPage.NavigationAction, preferences: inout WebPage.NavigationPreferences) async -> WKNavigationActionPolicy {
guard let webPage = webPage else { return .cancel }
// Handle case where target frame is nil (e.g., target="_blank" or window.open)
// This indicates a new window request
if action.target == nil {
print("Target frame is nil - new window requested")
// WORKAROUND: Until iOS 26 WebPage UI protocol is available, we handle new windows here
// Try to create a new WebPage through UI plugins
if handleCreateWebPage(for: webPage, navigationAction: action) != nil {
// Note: The new WebPage has been created and published to the view
return .allow
}
}
return .allow
}
I have developed a Swift macro called @CodableInit in the SwiftCodableMacro module, and I’m able to use it successfully in my main project.
Here’s an example usage:
import SwiftCodableMacro
@CodableInit // This is for Codable macros
public class ErrorMonitoringWebPlugin {
public var identifier: UUID = UUID()
// MARK: - Codable
required public init(from decoder:Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
identifier = try values.decode(UUID.self, forKey: .identifier)
}
}
However, when I try to write a unit test for the ErrorMonitoringWebPlugin class, I encounter an issue. Here's the test case:
func testCodableSubjectIdentifierShouldEqualDecodedSubjectIdentifier() {
self.measure {
let encoder = JSONEncoder()
let data = try? encoder.encode(subject)
//Here I am getting this error
Class 'JSONEncoder' requires that 'ErrorMonitoringWebPlugin' conform to 'Encodable'
let decoder = JSONDecoder()
let decodedSubject = try? decoder.decode(ErrorMonitoringWebPlugin.self, from: data!)
XCTAssertEqual(subject.identifier, decodedSubject?.identifier)
}
}
The compiler throws an error saying:
Class 'JSONEncoder' requires that 'ErrorMonitoringWebPlugin' conform to 'Encodable'
Even though the @CodableInit macro is supposed to generate conformance, it seems that this macro-generated code is not visible or active inside the test target.
How can I ensure that the @CodableInit macro (from SwiftCodableMacro) is correctly applied and recognized within the XCTest target of my main project?