iOS14,WKWebView 无法打开带有 _blank 目标的链接

iOS14, WKWebView cannot open links with _blank target

我有 WKWebView,我想用它来浏览某个网站。

然而,一些带有 target="_blank" 的链接并不总是打开。 从 运行 运行,我得到了不同的结果。

任何想法将不胜感激。

这是我的代码。 WebViewStore 由 SwiftUI 视图使用,这就是它是 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;
    }

这是 navDelegate,仅对某些链接调用!

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)
    }
}

这是我的 uiDelegate。我希望在需要新视图时调用它,我会在原始视图(相同)中加载它。

不幸的是,这个方法只是有时被调用...

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
    }
}

在撰写本文时,WKWebView 在解析 href 标记的 _blank 目标属性时存在一些“未知”错误。

当目标是_self 时,Safari 似乎可以正常工作。

想法是用 _self 替换所有 _blank 值。

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)
}