3

我正在尝试制作一个 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)
    }
}
4

1 回答 1

5

您目前的做法:

你已经混合了 watchOS 2 和 watchOS 3 方法。

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

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

watchOS 3 的更好方法:

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

始终使用 URLSession 后台传输上传和下载数据。后台传输发生在一个单独的进程中。即使在您的应用程序终止后,它们也会继续传输数据。另一方面,异步上传和下载会随您的应用程序暂停。鉴于 watchOS 应用程序的运行时间较短,您无法保证异步传输将在应用程序暂停之前完成。

通过让WKURLSessionRefreshBackgroundTask后台传输响应,您的扩展程序可以在会话完成后在后台唤醒,将该会话的数据移交给数据提供者,然后更新并发症。

关于数据提供者的建议:

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

我的印象是它意味着某种方式的单例(在幕后),但您将实例初始化为DataProvider().

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

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

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

您应该使用guardorif let首先检查您是否仍有活动并发症。

于 2016-06-29T13:44:11.170 回答