WKWeb 视图。didStartProvisionalNavigation 未调用

And*_*kha 3 webkit ios swift wkwebview

WKWebView在我的应用程序中使用,一切正常,直到用户转到money.cnn.com为止。对于本网站的主页,一切都很好,但是当用户离开主页并转到例如http://money.cnn.com/2016/11/21/news/dubai-trump-golf-course- developer/index.html?iid=hp-toplead-intl或此站点上的任何其他页面的委托方法didStartProvisionalNavigationdidCommitNavigation没有被调用。但是我需要这些方法来检测导航的开始。decidePolicyForNavigationAction在一开始就被调用,但是它被多次调用,我觉得使用这种方法不是一个完美的解决方案。所以我的问题是:在这种情况下我能做什么?在那个网站上有什么特别之处WKWebView调用它的委托方法,在这种情况下什么是可靠的解决方案?谢谢

Vas*_*huk 5

我不太了解网络开发,但在我看来,money.cnn.com 网站的 JavaScript 有问题。网站页面和它们的加载之间的转换似乎是在 JavaScript 的帮助下进行的。JavaScript 与本机 WKWebView 处理程序冲突。

但!您可以在页面的开头使用处理程序注入您自己的 JavaScript。当页面开始打开时,脚本将首先工作。

细节

  • Xcode 版本 10.2.1 (10E1001),Swift 5

完整示例代码

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    private weak var webView: WKWebView?
    private lazy var scriptName = "GetUrl"

    override func viewDidLoad() {
        super.viewDidLoad()
        setupWebView()
        loadUrl(string: "http://money.cnn.com/2016/11/21/news/dubai-trump-golf-course-developer/index.html?iid=hp-toplead-intl")
    }

    func setupWebView() {
        let contentController = WKUserContentController();
        let script = "webkit.messageHandlers.\(scriptName).postMessage(document.URL)"
        let userScript = WKUserScript(source: script, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true)
        contentController.addUserScript(userScript)
        contentController.add(self, name: scriptName)

        let config = WKWebViewConfiguration()
        config.userContentController = contentController

        let webView = WKWebView(frame:  UIScreen.main.bounds, configuration: config)
        webView.navigationDelegate = self
        view.addSubview(webView)
        self.webView = webView
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == scriptName {
            guard let url = message.body as? String else { return }
            if url.contains("http://money.cnn.com/") {
                print("!!! \(url)")
            } else {
                print("??? \(url)")
            }
        }
    }

    func loadUrl(string: String) {
        guard   let url = URL(string: string),
                let webView = self.webView else { return }
        webView.load(URLRequest(url: url))
    }
}
Run Code Online (Sandbox Code Playgroud)

信息表

添加您的 Info.plist 传输安全设置

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
Run Code Online (Sandbox Code Playgroud)

或者

在此处输入图片说明

结果

在此处输入图片说明

更多的

在 WKWebView 中从本机代码调用 JavaScript 函数