iOS WKWebView和web的交互

在web中注入代码通常使用的都是addUserScript(), 例如:

let script = "window.IOSMobileApp = true;"
let userScript = WKUserScript(source: script, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
let userContentController = WKUserContentController()
userContentController.addUserScript(userScript)

但是,实际使用的时候有的web界面已经成功注入了代码,却不会生效。所以需要更早的注入代码来实现,发现
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)方法中执行 evaluateJavaScript() 会比 addUserScript() 更早的注入js代码到web中去。
通过研究发现

func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)

调用时机:

  1. Main Frame开始加载时
  • 当Main Frame开始接收网页内容时调用
  • 此时已收到服务器的初始化响应
  • DOM开始构建但尚未完成 document.readyState为loading
  1. 页面重定向
  • 每次服务器端重定向(Http 3xx)后
  • 重定向链中的每个目标URL开始加载时会触发
  1. 前进/后退导航时
  • 使用历史记录导航(前进/后退)时
  • 页面加载前触发
  1. iframe加载时
  • 如果实现了webView(_: didCommit: )且没有限制Main Frame
  • 但通常只关注主框架的加载

使用场景
显示加载进度 / 重置页面状态 / 注入早期脚本

func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
  // 显示加载进度
  progressView.isHidden = false
  progressView.setProgress(0.1, animated: true)
  // 重置页面状态
  errorView.isHidden = true
  // 清除前一个页面的临时数据
  tempData = nil
  // 注入早期脚本
  let jsCode = "window.iOSApp = true;"
  webView.evaluateJavaScript(jsCode) { result, error in
            if let res = result as? Bool {
                print("执行结果\(res)")
            } else if let error = error {
                print("失败\(error.localizedDescription)")
            } else {
                print("js无效")
            }
        }
}
其他方法的执行顺序
  1. webView(_:decidePolicyFor: decisionHandler: ) -> 用户同意导航后
  2. webView(_:didStartProvisionalNavigation: ) -> 导航开始
  3. webView(_:didCommit: ) -> 内容开始加载
  4. webView(_:didFinish: ) -> 内容加载完成
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容