每次检测 WKWebView 何时完成加载
Posted
技术标签:
【中文标题】每次检测 WKWebView 何时完成加载【英文标题】:Detect when WKWebView has finished loading EVERY time 【发布时间】:2015-04-13 10:21:34 【问题描述】:我有一个在 iPad 上的 ios8 上运行的 WKWebView 应用程序(标准 iPad UserAgent:“Mozilla/5.0 (iPad; CPU OS 8_1_1 like Mac OS X) AppleWebKit/600.1.4 (Khtml, like Gecko) Version/8.0 Mobile/12B436 Safari/600.1.4")。我已经尝试了所有我能想到的委托和侦听器,每次都尝试检测页面何时完成加载。问题来了:
打开您的 WKWebView 并转到 Google。调用如下:
_decidePolicyForNavigationAction
_didStartProvisionalNavigation
_ didFinishNavigation
在 Google 中输入“YouTube”: 仅调用 _decidePolicyForNavigationAction。没有 didStartProvisionalNavigation 或 didFinishNavigation
在 Google 中点击 YouTube。调用如下:
_didStartProvisionalNavigation
_decidePolicyForNavigationAction
_ didFinishNavigation
从现在开始,在 YouTube 中什么都不会调用。单击 YouTube 视频,没有 didStartProvisionalNavigation 或 didFinishNavigation。此外,不再调用 webview.loading 观察者。甚至decisionPolicyForNavigationAction 也只是时不时地被调用。但是... webView.backForwardList.currentItem 在每次点击后都会更新,所以这一定是在检测页面何时以某种方式完成加载?
这种行为也发生在许多其他网站上(例如 Vimeo)。我知道这种类型的网站不会每次都更新主框架,但这是否缺乏检测加载何时开始/完成的能力是 WKWebView 在其当前状态下的“限制”?
我想要实现的是:是否有另一种方法来检测导航何时完成,每次在 YouTube/Vimeo 等 Java 移动网站中:
使用 NSURLProtocol 或类似的? 或者也许是一种检测何时 webView.backForwardList.currentItem 更新了吗?感谢您的帮助。
【问题讨论】:
查看***.com/questions/32660051/… 我使用 webview.scrollView.contentSize 属性来检查高度,如果它为零,那么我会在设置之前稍稍延迟调用相应的函数。 谢谢,但我不想检测 WKWebView 何时出现在屏幕上 - 我希望 WKWebView 在仅使用 Java 的网站(YouTube 移动设备、Vimeo 移动设备等)开始和结束加载时通知我在 iPhone 上的网站内点击。在 iPhone 上加载 YouTube 后,WKWebView 不会调用任何东西...您可以继续浏览该网站,并且不会调用任何委托方法。 Web 视图的问题在于,对于您无法控制的网站(因此可以插入特定的事件挂钩),一旦您开始尝试,“完成加载”的概念就开始变得非常难以定义一般把它固定下来。 javascript 在页面中加载和运行是现代复杂网站的典型特征,它可以通过非页面请求拉取内容,然后在原始 HTML 及其资源完全下载并构建 DOM 后填充页面。这就是您在 YT 和 Vimeo 中看到的。从技术上讲,该页面无法在任何地方导航。 快速解决方案:***.com/a/40730365/4488252 【参考方案1】:我不确定页面加载后您到底想做什么,但希望观察这些属性可以帮助您:
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)
webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil)
webView.addObserver(self, forKeyPath: "title", options: .New, context: nil)
webView.addObserver(self, forKeyPath: "canGoBack", options: .New, context: nil)
webView.addObserver(self, forKeyPath: "canGoForward", options: .New, context: nil)
【讨论】:
这是唯一对我有用的东西——对估计的进度做出反应。有时即使 wkwebview 进度不是 1 并且文档显然仍在加载,也会调用 jquery ready。 上面有没有基于观察者触发方法的demo代码? 非常感谢;这对我帮助很大!但为了完全可靠,我必须将“URL”添加到观察到的键路径列表中!【参考方案2】:如果有人正在寻找如何使用观察者的解决方案,这里是解决方案:
webView.addObserver(self, forKeyPath: "title", options: .new, context: nil);
webView.addObserver(self, forKeyPath: "loading", options: .new, context: nil);
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil);
然后使用observeValue
函数并编写一个switch-case或if-else来找到keyPath
。
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
if keyPath == "title"
print(change ?? "No title")
if change != nil, let currentTitle = change?[.newKey] as? String
titleLabel.text = currentTitle
else if keyPath == "loading"
print("Loading")
reloadButton.setImage(#imageLiteral(resourceName: "cancel.png"), for: .normal)
else if keyPath == "estimatedProgress"
print(wkWebView.estimatedProgress);
progressView.progress = Float(wkWebView.estimatedProgress)
Here我创建了一个演示项目来探索更多关于 WebKit WebView 的信息。
【讨论】:
以上是关于每次检测 WKWebView 何时完成加载的主要内容,如果未能解决你的问题,请参考以下文章
检测用户何时点击加载在 UIWebView 或 WKWebView 中的 web 表单
如何检测 amp 页面的 url 何时随 WKWebview 更改
检测用户何时向左或向右滑动以在 WKWebView 上前后移动
WKWebView:应用程序因“NSInternalInconsistencyException”异常而崩溃,因为“未调用传递给 X 的完成处理程序”