I have gone through a lot of different StackOverflow threads & Apple Developer pages to figure out what is going on here. I believe I am so close.
I have a WebView that runs on a site for a bit. Eventually the user can click a link that would open a new tab. It is opened via a window.open() call in JavaScript in the HTML.
However, on SwiftUI nothing runs, and I have set-up what should be the proper UIDelegate. This function never gets entered as I step through the call to WebView.
My question is: How can I make sure the UIDelegate is properly set? Where does this occur? Do I have the right spot?
My implementation (shortened):
struct WebView: UIViewRepresentable {
var url: URL
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
// Enable javascript in WKWebView to interact with the web app
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
preferences.javaScriptCanOpenWindowsAutomatically = true
let configuration = WKWebViewConfiguration()
// Here "iOSNative" is our interface name that we pushed to the website that is being loaded
// configuration.userContentController.add(self.makeCoordinator(), name: "iOSNative")
configuration.preferences = preferences
let webView = WKWebView(frame: CGRect.zero, configuration: configuration)
// webView.navigationDelegate = context.coordinator
// webView.uiDelegate = context.coordinator
// webView.allowsBackForwardNavigationGestures = true
// webView.scrollView.isScrollEnabled = true
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.uiDelegate = context.coordinator
webView.navigationDelegate = context.coordinator
webView.load(request)
}
class Coordinator : NSObject, WKUIDelegate, WKNavigationDelegate {
var parent: WebView
var webViewNavigationSubscriber: AnyCancellable? = nil
init(_ uiWebView: WebView) {
// uiWebView.uiDelegate = self
self.parent = uiWebView
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// Suppose you don't want your user to go a restricted site
if navigationAction.targetFrame == nil {
if let url = navigationAction.request.url {
UIApplication.shared.open(url)
decisionHandler(.allow)
return
}
}
func webView(webView: WKWebView!, createWebViewWith configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! {
// if navigationAction.targetFrame == nil {
// UIApplication.shared.open(navigationAction.request.url!)
// }
// return nil
if (!(navigationAction.targetFrame?.isMainFrame ?? false)) {
webView.load(navigationAction.request)
}
return nil
}
func webView(webView: WKWebView!, createWebViewWithConfiguration configuration: WKWebViewConfiguration!, forNavigationAction navigationAction: WKNavigationAction!, windowFeatures: WKWindowFeatures!) -> WKWebView! {
if navigationAction.targetFrame == nil {
UIApplication.shared.open(navigationAction.request.url!)
}
return nil
}
}
}
My thoughts:
- Am I assigning uiDelegate & navigationDelegate in the right spots? It doesn't seem that my
createWebViewWith
delegate ever gets called. The app opens HTML links in tags with target = "_blank", it's just this one that is called via window.open(x) in javascript.
My resources: WKWebView and window.open Window.open() is not working in WKWebView https://developer.apple.com/forums/thread/664267 https://developer.apple.com/forums/thread/68427