1

我想要实现的是以下内容:

  1. 并发症在后台每隔 30 分钟更新一次
  2. 每当手表应用程序运行并接收到自己的更新数据时,并发症就会得到更新
  3. 每当 iOS 应用程序运行并且用户更改影响手表数据的设置(例如更改天气观测的位置或显示单位)时,都会更新复杂功能

第 1 项和第 2 项似乎很简单,在这里很好地解决了:更新 Apple Watch 复杂数据的流程是什么?

但是,对于第 3 项,在 iOS 应用程序中,我设置了一个 WCSession 实例并调用 transferCurrentComplicationUserInfo,将新设置作为 NSDictionary 发送。在监视扩展中,这会调用 WCSessionDelegate 中的 didReceiveUserInfo。

- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo {
    // Code here to apply the new settings
    // ....
    // Invoke a NSUSRLSession-based web query to get new data
    [self queryForNewDataWithCompletionHandler:^(NCUpdateResult result) {
        if (result == NCUpdateResultNewData) {
            // Have new data from web to display
            CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
            for (CLKComplication *complication in server.activeComplications) {
                [server reloadTimelineForComplication:complication];
            }
        }
        // Set date for next complication update to 30 mins from now
        // ...
    }];
}

我遇到的问题是 watchOS 在一个单独的线程中调用了 requestedUpdateDidBegin,在它调用 didReceiveUserInfo 之后不久,它开始执行,然后我有机会使用从应用程序新收到的 UserInfo 字典中的新设置获取更新的数据。

因此,并发症会在短时间内连续更新两次 - 一次是由 WatchOS 调用了 requestedUpdateDidBegin,它只是使用现有(陈旧)数据重新更新并发症,然后我很快从网络接收到新数据然后必须更新它们再次在我自己的代码中。

这似乎没有必要并且浪费资源,更不用说 Apple 允许的有限更新预算(据说每小时 2 次)。

我在这里做错什么了吗?在我有机会从网络获取新数据之前,如何防止 watchOS2 调用 requestedUpdateDidBegin?

4

1 回答 1

2

的目的transferCurrentComplicationUserInfo是立即将当前的复杂数据传递给扩展。在您的代码中,您正在传递设置,但是您没有包含任何天气数据。

您看到的问题源于尝试在扩展中异步获取新数据(在数据可用之前返回)。

要处理这个问题,您应该根据新设置获取手机上的当前天气数据,然后在当前复杂用户信息中传递(新设置以及)天气数据。

- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo {
    // Code here to apply the new settings for future updates
    // ....
    // Code here to update cache/backing store with current weather data just passed to us
    // ....

    CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
    for (CLKComplication *complication in server.activeComplications) {
        [server reloadTimelineForComplication:complication];
    }
}

这样,复杂功能服务器可以使用您刚刚传输到手表的当前复杂功能数据立即更新时间线。

没有陈旧的数据,没有不必要的第二次更新。

于 2016-01-12T22:57:39.853 回答