iOS WKWebView JS在后台应用程序时不更新属性修改

Posted

技术标签:

【中文标题】iOS WKWebView JS在后台应用程序时不更新属性修改【英文标题】:iOS WKWebView JS doesn't update attribute modification when app in background 【发布时间】:2017-09-11 14:26:37 【问题描述】:

嘿,我有一个带有 Watch Extension 的 ios 应用。当启动 Apple Watch 应用程序时,它会启动 iPhone 应用程序并通过每隔几秒钟发送一次sendMessage 呼叫来保持其活动状态。然后,iPhone 应用程序导航到 WKWebView 中的网站,每隔几秒钟检查一次其内容,然后将一些数据发送到 Apple Watch 以便在那里显示。

在 Apple Watch 上显示不断更新的内容效果很好,我在 iPhone 上得到的数据是这样的:

self.webView.evaluatejavascript("document.documentElement.outerhtml.toString()",
                                   completionHandler:  (html: Any?, error: Error?) 

. . . //splitting html content into TFHppleElements

self.contentArray.add((element.search(withXPathQuery: "//div[contains(@class, 'article-title')]")[0] as AnyObject).content)

我每 5 秒运行一次。只要article-title 中的文本发生更改,更改就会在我的手表上可见。有效。

这些元素都包含style="z-index: 206; height: ... 之类的东西,我通过抓取属性然后将其子串起来成功地解析了它。

let styleContainer = element.attributes["style"] as! String
var firstHalf = styleContainer.components(separatedBy: "; height:")
...

我使用 z-index 值对 Apple Watch 上的表格行进行排序,但在 1-3 次更新后,所有元素的 z-index 停止更新。内容(如文章标题)仍在更新,因此数据流肯定可以正常工作,但我想知道为什么 z-index' 保持不变。起初我认为这是我的排序问题或转移到 Apple Watch 期间的问题,但我无法确定这个问题 - 当我在 iPhone 上运行应用程序时,它总是得到正确的索引,但是当我运行应用在手表上启动,出现上述问题。

在处理数据结构数天后(仍然认为错误在我这边),它终于击中了我:当应用程序在后台启动时,页面本身的 z-index 没有得到更新。我通过在我的手表上启动应用程序并像往常一样获取错误的 z-index' 来检查这一点,但随后我保持手表应用程序打开并在 iPhone 上启动应用程序 - 我看到 WKWebView 根据更新元素的顺序到他们的 z-index,突然间我得到了每个元素的正确 z-index,即使在按下主页按钮后也是如此。这解释了很多,但仍然不能真正帮助我解决问题。

如何欺骗 WKWebView 在后台运行时让 JS 更新所有元素 z-index? 我觉得奇怪的是打开 iPhone 后不会出现此问题应用程序在短时间内,但我不能要求我的用户每次想要访问 Watch 应用程序时都打开并“最小化”应用程序,因为 Watch 应用程序的目的是将手机放在口袋里。

通过sendMessage 激活 iPhone 应用程序也会调用 viewDidLoad,因此我可以指出在手机上手动启动应用程序和通过 Watch 启动应用程序之间没有真正的区别。 Javascript 本身也可以在后台运行,那么为什么除了 z-index 属性之外的所有内容都会更新?就保持电池寿命而言,防止“图形”更新在后台运行是可以理解的,但文本也不是“图形”的吗?如果手动启动 home-buttoned 应用程序,为什么会有所不同?

移除了,因为下面只发生过一次,很奇怪。

编辑:好的,实际上索引值发生了变化,但是每当一篇文章被推到顶部时,它就会与任何文章的最高值相同,而不会更新其他文章的值。 示例:

Before:
A1: 26
A2: 27
A3: 28
A4: 29
After pushing A1 to the top in the background:
A2: 27
A3: 28
A4: 29
A1: 29
After manually opening the app on the phone:
A2: 26
A3: 27
A4: 28
A1: 29

WebKit 似乎有issues with the z-index 所以让我们看看旅程将我带向何方

【问题讨论】:

【参考方案1】:

您好,我不确定我对这个问题有明确的答案,但我确实有一些事情可以帮助您。

首先,您需要在 WKWebView 中查看 HTML / CSS,为此,您可以打开 Safari 并在顶部栏上单击“开发”,然后第三项应该是您的计算机名称将打开可见 WebView 实例的列表。您可以单击当前正在运行的那个(当您将鼠标悬停在该选项上时,您应该会看到屏幕突出显示)。打开它,然后您可以查看源代码、样式和使用控制台。

从这里尝试确定 Z-Index 是否真的在 WebView 中更新。如果它们不是我怀疑的那样,这会让我相信这是一个缓存问题。根据我的经验,使 WKWebView 比传统 UIWebView 性能更高的一件事是它具有的缓存机制。它会尝试缓存所有可以缓存的 CSS,因此您可能需要尝试在加载之间清除缓存。

let dataTypes = NSSet(array: [WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache, WKWebsiteDataTypeLocalStorage])
let epoch = NSDate(timeIntervalSince1970: 0)
WKWebsiteDataStore.default().removeData(ofTypes:dataTypes as! Set<String>, modifiedSince:epoch as Date, completionHandler:)

请注意,WKWebViews 的所有实例共享相同的数据存储,因此您实际上并未清除 WebView 实例上的数据,而是清除 WKWebSiteDataStore 上的数据。

我也会使用 javascript 来重新加载页面:

webView.evaluateJavaScript("location.reload();", completionHandler: nil)

如果这些解决方案没有帮助,我会尝试重新组织列表,而不是使用名称或 id 标记使用 ZIndex,这些可能没有与 CSS 相同的缓存问题。希望这会有所帮助,但如果不深入研究,就很难确定问题出在哪里。

【讨论】:

嘿,我首先从 chrome 的开发人员工具中注意到 z-Index,我明天会研究你告诉我的内容。我正在谈论的网站是 web.whatsapp.com。这是关于消息列表的。 我会使用 Safari 的开发工具来查看它们,因为即使这些工具在 Safari 中,您也会准确地看到 WKWebView 看到的内容,这可能与您在 Chrome 中看到的内容有所不同。跨度> 嘿伙计,这个月真的很忙,所以现在回到正题:我尝试将 Safari 附加到 iOS 模拟器,我不知道这是可能的,谢谢。但是,z-index 确实似乎保持不变 - 直到我将应用程序带到前台。我尝试查找添加消息时更改的任何标签,但找不到任何内容。我最终可能会解释每条消息附带的“时间”标签,但我仍然非常希望 z-index 在后台工作。我尝试了您的 3 行代码,每分钟多次调用它们但没有成功。还有其他想法吗?

以上是关于iOS WKWebView JS在后台应用程序时不更新属性修改的主要内容,如果未能解决你的问题,请参考以下文章

iOS:在 WKWebView 中嵌入视频在后台停止音乐

在 iOS 中 WKWebView 的后台历史显示带有父 URL 的子 URL

vue.js 是不是在 wkwebview 上正常工作

Flutter IOS 通知的 FCM 在应用程序处于后台或终止时不显示

外部JS可以在iOS WkWebView中的加载页面(完成时)上执行吗

iOS下JS与OC互相调用--WKWebView 拦截URL