'iOS14, WKWebView cannot open links with _blank target
I have WKWebView that I want to use to browse a certain web site.
However some links with target="_blank" are not always opening. From run to run, I get different results.
Any ideas will be highly appreciated.
Here is my code. the WebViewStore is used by a SwiftUI View, that's why it is ObservableObject.
public class WebViewStore: NSObject, ObservableObject {
@Published public var navDelegate = WebViewNavDelegate();
@Published public var uiDelegate = WebViewUIDelegate();
@Published public var webView: WKWebView = WKWebView() {
didSet {
log.info("WebViewStore.webView new WebView !!!")
setupObservers()
}
}
override public init() {
super.init();
log.info("WebViewStore.init")
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistent()
configuration.preferences = preferences
let webView = WKWebView(frame: CGRect.zero, configuration: configuration)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.allowsLinkPreview = true
webView.allowsBackForwardNavigationGestures = true
webView.isUserInteractionEnabled = true
webView.uiDelegate = uiDelegate;
webView.navigationDelegate = navDelegate;
self.webView = webView;
}
This is the navDelegate this is called only for some of the links!
public class WebViewNavDelegate : NSObject, WKNavigationDelegate, ObservableObject {
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
log.info("WebViewUI.webView : 6 - decidePolicyFor" )
isLoading = true;
log.info("url: \(navigationAction.request.url!.absoluteString)")
log.info("target: \(navigationAction.targetFrame?.description)")
// This allows the navigation
decisionHandler(.allow)
}
}
Here is my uiDelegate. I expect this to be called when new view is required, I would load it in the original (the same).
Unfortunately this method is called only sometimes ...
public class WebViewUIDelegate : NSObject, WKUIDelegate {
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
log.info("WebViewUIDelegate.webView() (createWebViewWith)")
log.info("url: \(navigationAction.request.url?.absoluteString)" )
log.info("target: \(navigationAction.targetFrame)" )
if navigationAction.targetFrame == nil {
webView.load(navigationAction.request)
}
return nil
}
}
Solution 1:[1]
At the moment of writing this, WKWebView has some "unknown" bug with parsing the _blank target attributes of href tag.
It seems that Safari works properly when the target is _self.
The idea is to replace all _blank values with _self.
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
let jsCode = "var allLinks = document.getElementsByTagName('a');if (allLinks) { var i;for (i=0; i<allLinks.length; i++) {var link = allLinks[i];var target = link.getAttribute('target');if (target && target == '_blank') {link.setAttribute('target','_self');} } }"
webView.evaluateJavaScript(jsCode, completionHandler: nil)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Deian |