【问题标题】:WKWebView: Issues with opening links in SafariWKWebView:在 Safari 中打开链接的问题
【发布时间】:2020-04-02 20:29:15
【问题描述】:

在我开始之前,应该注意我的问题的 部分this 帖子的副本,该帖子没有可接受的答案。此外,我还阅读了其他几篇与我的问题相似但不准确的 SO 帖子,例如 thisthis

问题:

我使用 WKWebView 来显示用 HTML 标记的文本。一些文本包含链接,我希望在点击时在 Safari 中打开这些链接。我已经走了很远,但我仍然遇到 2 个主要问题。

1) WKWebView 不响应会话的第一次点击,即,必须点击第一个链接两次才能打开 Safari。之后点击任何链接都会立即打开 Safari。

2) Safari 仅打开被点击的第一个链接的 URL。假设正在显示 3 个 URL:A、B 和 C。如果首先点击 A,那么只要初始化 WKWebView,点击其他 2 个 URL 中的任何一个都将始终打开 Safari 到 A。如果先点击B,Safari只会对B等开放。

这是我认为与这个问题最相关的 Swift 代码:

class CustomWebView: WKWebView, WKUIDelegate, WKNavigationDelegate {

    convenience init() {

        let config = WKWebViewConfiguration()
        config.dataDetectorTypes = [.all]

        self.init(frame: .zero, configuration: config)
        navigationDelegate = self
        uiDelegate = self
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (_: WKNavigationResponsePolicy) -> Void) {
        decisionHandler(.allow)
    }

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

        if let url = navigationAction.request.url {
        print("url: \(url)")

            let paths = url.absoluteString.components(separatedBy: ",")
            print("paths: \(paths)")

            for path in paths {

                if path.contains("link:") {

                    let link = path.replacingOccurrences(of: "link:", with: "").replacingOccurrences(of: "%22", with: "")
                    print("link: \(link)")

                    if let cleanedURL = URL(string: link) {
                    print("cleanedURL: \(cleanedURL)")

                        UIApplication.shared.open(cleanedURL, options: [:], completionHandler: nil)
                        decisionHandler(.cancel)
                        return
                    }
                }
            }
        }
        decisionHandler(.allow)
    }
}

这是我正在测试的一些示例 HTML:

<a href="https://www.bbc.com/">https://www.bbc.com/</a>
<div>
    <br />
</div>
<div><a href="https://www.youtube.com/">https://www.youtube.com/</a>
    <br />
</div>
<div>
    <br />
</div>
<div><a href="https://stackoverflow.com/">https://stackoverflow.com/</a>
    <br />
</div>

以下是打印语句显示的内容:

第 1 步

点击链接A:

网址:callback://0/underline,justifyLeft,textColor

路径:["callback://0/underline", "justifyLeft", "textColor"]

第 2 步

再次点击链接 A:

网址:callback://0/underline,justifyLeft,textColor,link:https://www.bbc.com/

路径:["callback://0/underline", "justifyLeft", "textColor", "link:https://www.bbc.com/"]

链接:https://www.bbc.com/

cleanedURL:https://www.bbc.com/

第 3 步

在执行第 2 步后点击链接 A、B 或 C 会得到与第 2 步相同的打印语句。

其他说明:

HTML 来自ZSSRichTextEditor,它在应用程序的另一部分实现,让用户输入标记的 HTML。有时,当用户输入链接时,编辑器吐出的 HTML 会将其包围在 %22 中,这就是我在上面的代码中将其删除的原因。

【问题讨论】:

    标签: ios swift safari wkwebview rich-text-editor


    【解决方案1】:

    您可以尝试检查操作的类型。

      func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void) {
        if navigationAction.navigationType == .linkActivated,
          let reqURL = navigationAction.request.url {
          UIApplication.shared.open(reqURL, options: [:], completionHandler: nil)
          decisionHandler(.cancel)
    
        } else {
          decisionHandler(.allow)
        }
      }
    

    但问题是许多网站拦截了链接元素上的点击动作,以触发 JavaScript 中的导航。这些最终会作为.other 导航操作发送到decidePolicyFor,而不是.linkActivated

    【讨论】:

    • 感谢您的回复。您的检查可能是个好主意,但不会影响我遇到的任何问题。
    • 您能谈谈您正在显示的 HTML 吗?它是您或您的公司拥有的网站吗?或者您是否需要在 Safari 中打开任何网站的链接?
    • WebView 显示用户在不同场景中输入的标记文本,因此他们可以链接到任何网站。在我的示例中,A 和 C 是不同的 SO 链接,B 是 YouTube 链接。这些问题与 HTML 中的 URL 是什么无关。似乎正在发生的事情是,对于问题 2) WebView 正在做一些事情,比如缓存打开的第一个链接并忽略连续的 URL。对于问题 1),可能是加载问题。
    • 是的,目标 URL 无关紧要,但链接元素可能。他们是普通的&lt;a href&gt; 吗?他们有"target=_blank" 吗?他们有click 事件吗?如果您也发布该 HTML 的示例,可能会有所帮助。另外我不认为 webviews 缓存链接。我会尝试在decidePolicyFor 中放置一个print 命令来检查navigationAction
    • 我已经编辑了我的问题以包括我正在测试的 HTML,以及它打印出来的内容以及它来自何处的解释。感谢您坚持这一点;希望对您有所帮助!
    猜你喜欢
    • 2015-08-16
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多