watchkit - reloadTimeline() 不更新复杂性

标签 watchkit apple-watch-complication clockkit watchos-3 wkrefreshbackgroundtask

我正在尝试制作一个 watchOS 3 应用程序,并且我想在后台任务中更新我的复杂功能。

首先,我在 handle() 内的后台任务中从服务器获取新数据。之后,我通过调用 complicationServer.reloadTimeline(for:) 更新我的事件并发症。

在控制台中,我确实看到了消息“UPDATE COMPLICATION”,因此代码被执行。

但是重新加载后,并发症仍然显示旧数据。如果我切换表盘并切换回来,复杂功能有时会重新加载。我是否需要执行其他操作才能从后台任务重新加载复杂功能?

func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    for task : WKRefreshBackgroundTask in backgroundTasks {
        if (WKExtension.shared().applicationState == .background) {
            if task is WKApplicationRefreshBackgroundTask {
                let dataProvider = DataProvider()
                dataProvider.getData(station: "Name", completion: { (data, error) in
                    self.updateComplication()
                    self.scheduleNextBackgroundRefresh()

                    task.setTaskCompleted()
                })
            }
        } else {
            task.setTaskCompleted()
        }
    }
}

func updateComplication() {
    let complicationServer = CLKComplicationServer.sharedInstance()

    for complication in complicationServer.activeComplications! {
        print("UPDATE COMPLICATION")
        complicationServer.reloadTimeline(for: complication)
    }
}

最佳答案

您当前的方法:

您可以混合使用 watchOS 2 和 watchOS 3 方法。

  • WKApplicationRefreshBackgroundTask(新的 watchOS 3 方法)
    1. DataProvider 启动异步传输(旧的 watchOS 2 方法假设它位于前台,而不是后台)。
      • 一旦异步传输完成,后台线程(可能会或可能不会挂起但未完成的后台任务)期望让后台任务处理其完成。

简而言之,您希望后台刷新任务在后台等待异步传输。这有点复杂(因为刷新任务应该在后台执行工作,而不是等待其他工作完成)。

watchOS 3 的更好方法:

由于异步传输可以暂停,因此最好使用 URLSession 后台传输。

Always upload and download data using an URLSession background transfer. Background transfers occur in a separate process. They continue to transfer the data even after your app has terminated. Asynchronous uploads and downloads, on the other hand, are suspended with your app. Given the short run time of watchOS apps, you cannot guarantee that an asynchronous transfer will finish before the app is suspended.

通过让 WKURLSessionRefreshBackgroundTask 响应后台传输,一旦 session 完成,您的扩展程序就可以在后台被唤醒,将该 session 的数据移交给数据提供者,然后更新复杂功能。

有关数据提供者的建议:

它似乎既负责传输数据,又负责提供数据。您可能需要考虑将网络部分拆分为一个单独的组件,并简单地将其作为数据存储库。

我的印象是,它应该是某种形式的单例(在幕后),但您将实例初始化为 DataProvider()

从可读性的角度来看,从提供的代码来看,复杂数据源将使用与接收数据的数据提供者相同的数据提供者并不明显。

您应该避免强制展开选项:

activeComplications 为零时(例如,在上次更新和本次更新之间从表盘上删除了复杂功能时),您的代码将不礼貌地崩溃。

您应该使用 guardif let 首先检查您是否仍然存在活跃的并发症。

关于watchkit - reloadTimeline() 不更新复杂性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38097981/

相关文章:

ios - CLKComplicationTemplateUtilitarianSmallRingImage 不显示图像

swift - 为 getRequestedUpdateDateWithHandler 构造日期 :

ios - Apple 是否将 NSUserDefaults 共享从 iOS 应用更改为 watchOS 应用

swift - WKinterfacePicker 项目问题

watchkit - 对于 Watch Complication 和 Time Travel,getTimelineEntriesForComplication 被(太)经常调用

performance - 更新复杂功能会逐渐降低 watchOS3 中 Apple Watch 应用程序的性能

xcode - 从我的 Watch 应用程序中删除并发症

ios - 如何在 Apple Watch 应用程序中实现摇动手势?

swift - 通过 ClockKit 并发症显示心率?

watchkit - 处理 watch 并发症时 Xcode 中的错误消息