如何正确实现从iOS应用程序到watchOS2复杂的设置传输

我想要实现的目标如下:

  1. 并发症在30分钟的间隔内在后台更新
  2. 每当手表应用程序运行并接收其自己的更新数据时,复杂性就会更新
  3. 每当iOS应用程序运行并且用户更改影响监视数据的设置(例如更改天气观察的位置或显示单位)时,复杂function就会更新

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

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

- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary *)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?

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

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

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

 - (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary *)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]; } } 

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

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