一旦已经在 WebView 中,如何使用 WKWebView 打开外部 link?

How to open external link with WKWebView once already inside WebView?

我一直在 YouTube 上,所以,google 过去 3 小时,我找不到答案。

我可以通过 webView 打开初始 link 到 instagram,一旦我进入 webView 并转到某人的简历并按任何 link 他们没有任何反应。

我去了 .plist 并启用了 App Transport Security > Arbitrary Loads > YES

我尝试了 decidePolicyFor navigationAction: WKNavigationAction 但没有任何反应:

class ViewController: WKNavigationDelegate {

    var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let url = URL(string: "https://www.instagram.com/apple") else { return }
        let request = URLRequest(url: url)

        webView.load(request)
        webView.allowsBackForwardNavigationGestures = true

        webView.addObserver(self, forKeyPath: #keyPath(WKWebView.isLoading), options: [.new], context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "loading" {
            if webView.isLoading {
                view.addSubview(spinner)
            } else {
                spinner.removeFromSuperview()
            }
        }
    }

    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        switch navigationAction.navigationType {
        case .linkActivated:
            if navigationAction.targetFrame == nil {
                self.webView?.load(navigationAction.request)
            }
            if let url = navigationAction.request.url, !url.absoluteString.hasPrefix("http://www.myWebSite.com/example") {
                DispatchQueue.main.async {
                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
                }
                print(url.absoluteString)
                decisionHandler(.cancel)
                return
            }
        default:
            break
        }

        if let url = navigationAction.request.url {
            print(url.absoluteString)
        }
        decisionHandler(.allow)
    }

    // tried this too
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        var action: WKNavigationActionPolicy?

        defer {
            decisionHandler(action ?? .allow)
        }

        guard let url = navigationAction.request.url else { return }

        print(url)

        if navigationAction.navigationType == .linkActivated, url.absoluteString.hasPrefix("http://www.example.com/open-in-safari") {
            action = .cancel
            DispatchQueue.main.async {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
        }
    }
}

您还需要遵守 WKUIDelegate

webView.uiDelegate = self

因为你没有,所以这个委托方法没有触发。

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView?