widgetPerformUpdateWithCompletionHandler()
让我们可以让通知中心知道 Today Extension 的内容是否发生了变化。例如:
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
// Refresh the widget's contents in preparation for a snapshot.
// Call the completion handler block after the widget's contents have been
// refreshed. Pass NCUpdateResultNoData to indicate that nothing has changed
// or NCUpdateResultNewData to indicate that there is new data since the
// last invocation of this method.
if(has_new_data()) { // There was an update
completionHandler(.NewData)
}
else { // nothing changed!
completionHandler(.NoData)
}
}
但是我们怎么知道内容是否发生了变化呢?在每个快照上,小部件都是从头开始实例化的。这是一个具有新PID的全新进程。所以你不能在你的实例中存储任何属性。如何将当前小部件内容与前一个快照的内容进行比较?
我使用 Core Data 来存储当前内容以供以后比较。这很明显并且有效。但随后另一个问题崩溃了:如果没有以前的快照怎么办?假设用户删除了小部件只是为了重新添加它。或者用户重新启动。可能还有更多原因导致我现在想不到以前没有快照。无论哪种方式 - Core Data 中仍然存储有内容。如果此旧内容与当前内容之间的比较检测到没有更改并且我返回.NoData
的小部件最终会为空,因为通知中心不会重绘内容。
您可能想知道为什么以正确的状态调用 对我来说如此重要,completionHandler
而不是简单地总是 return .NewData
。那是因为当没有变化并且仍然返回时我正在经历一点闪烁.NewData
。我的小部件中有一些图像,当重绘小部件时,整个内容会在一毫秒内不可见 - 足以引起注意。
有什么我想念的吗?对我来说很奇怪的是,Apple 提供了一种方法,让我们可以选择以不同的状态进行响应,但却无法检测到我们应该响应哪个状态。