【问题标题】:ScriptMessageHandler not always called on actual device, works fine on simulatorScriptMessageHandler 并不总是在实际设备上调用,在模拟器上工作正常
【发布时间】:2016-02-14 21:59:39
【问题描述】:

我使用WKWebView,我希望在网站完全加载时收到通知。当document.readyStateinteractivecomplete 时,WKNavigationDelegatewebView:didFinishNavigation 方法被触发,我想确保该站点已完全加载。我想出了使用 JavaScript 注入的解决方案。这是我的 MWE:

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {

    var webView: WKWebView!

    @IBOutlet weak var loadLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        let contentController = WKUserContentController()

        let scriptPath = NSBundle.mainBundle().pathForResource("script", ofType: "js")!
        let scriptString = try! String(contentsOfFile: scriptPath)
        let script = WKUserScript(source: scriptString, injectionTime: .AtDocumentStart, forMainFrameOnly: true)

        contentController.addUserScript(script)
        contentController.addScriptMessageHandler(self, name: "readyHandler")

        let configuration = WKWebViewConfiguration()
        configuration.userContentController = contentController

        webView = WKWebView(frame: CGRect.zero, configuration: configuration)
        webView.navigationDelegate = self
        loadLabel.text = nil
    }

    @IBAction func loadWebsite() {
        webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://stackoverflow.com")!))
        loadLabel.text = "Loading..."
    }

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
        print("message received")
        loadLabel.text = "Complete"
    }
}

这是script.js文件的内容:

document.onreadystatechange = function () {
    if(document.readyState === "complete"){
        webkit.messageHandlers.readyHandler.postMessage("");
    }
}

userContentController:didReceiveScriptMessage 方法总是在 iOS 模拟器上调用,但在实际设备上(在我的情况下是 iPhone 6)上,大多数时候都不会调用它。知道它可能有什么问题,或者检查网站是否完全加载的另一种方法是什么?

【问题讨论】:

  • .AtDocumentEnd 工作吗?
  • @soflare 在模拟器上,是的,在设备上,不是。更有趣的是,我在另一台设备(带有 iOS 8.4.1 的 iPhone 5)上对其进行了测试,它运行良好。所以这看起来像是 iOS 9 本身的问题。
  • 确保: 1. 脚本被注入; 2.脚本执行; 3. 消息送达。哪一步坏了?尝试使用 Safari 附加 webview 并在 JS 控制台中检查。

标签: ios swift webkit wkwebview


【解决方案1】:

出于某种原因,您需要将 webView 添加到可见视图中才能在设备上工作。如果您不希望 webView 可见,请添加它,然后将 hidden 属性设置为 true。

对于上面的代码示例:

func viewDidLoad(){
   ...
   webView.hidden = true
   view.addSubview(webView)
}

【讨论】:

  • 不幸的是,无法将此 webView 添加到某些可见视图控制器 - 我需要此功能用于将网页导出为 pdf 的框架。我将尝试使用 webview 创建视图控制器,但实际上不会向用户显示。我猜这个技巧 - natashatherobot.com/ios-testing-view-controllers-swift - 可能在这里奏效。
  • 我在我的项目中遇到了同样的问题,所有 requireJS 调用都挂起。正如 xoogler 所提到的,根本原因是在加载网站/页面之前,Web 视图必须是视图层次结构的一部分。我的项目是一个框架,因此它不拥有封闭视图,也无法将 Web 视图添加到层​​次结构中。所以我必须修改我的 API 以通知客户端在加载 Web 内容之前将 Web 视图添加到层​​次结构中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多