如何正确实现将设置从iOS应用转移到watchOS2并发症 [英] How to correctly implement transfer of settings from iOS app to watchOS2 complication

查看:107
本文介绍了如何正确实现将设置从iOS应用转移到watchOS2并发症的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要实现的目标如下:

  1. 并发症在后台每隔30分钟更新一次 分钟
  2. 手表应用程序运行时,并发症会不断更新,并且 接收自己的更新数据
  3. 并发症随时更新 iOS应用会运行,并且用户会更改一个设置,该设置会影响 观看数据(例如更改天气预报的位置,或 显示单位)
  1. Complication(s) get updated in the background at intervals of 30 minutes
  2. Complication(s) get updated whenever the watch app runs and receives its own updated data
  3. Complication(s) get updated whenever the iOS app runs and the user changes a setting which affects the watch data (such as changing location of weather observations, or display units)

第1项和第2项似乎很简单,可以在这里很好地解决:

Items 1. and 2. seem to be straightforward, and nicely addressed here: What is the flow for updating complication data for Apple Watch?

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

However, for item 3, in the iOS app, I set up a WCSession instance and call transferCurrentComplicationUserInfo, sending the new settings as NSDictionary. In the watch extension, this invokes didReceiveUserInfo in WCSessionDelegate.

- (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调用了didReceiveUserInfo之后不久,watchOS在一个单独的线程中调用了requestedUpdateDidBegin,并且此方法开始执行之前,我有机会使用来自应用程序的新接收到的UserInfo词典中的新设置获取更新数据.

The problem I am having is that watchOS is calling requestedUpdateDidBegin in a separate thread, shortly after it invoked didReceiveUserInfo and this starts executing BEFORE I have a chance to obtain updated data using the new settings in the newly received UserInfo dictionary from the app.

因此,并发症在短时间内连续两次被更新-WatchOS调用了requestedUpdateDidBegin,一次简单地用现有(陈旧的)数据更新并发症,然后我很快就从网络上接收到新数据,然后用我自己的代码再次更新它们.

Consequently, the complications get updated twice in short succession - once by the WatchOS having called requestedUpdateDidBegin, which simply re-updates the complication with existing (stale) data, before I very soon after receive new data from the web and then have to update them again in my own code.

这似乎不必要,而且浪费资源,更不用说Apple允许的有限更新预算了(每小时2个).

This seems unnecessary and a waste of resources, not to mention the limited budget of updates that Apple allows (supposedly 2 per hour).

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

Am I doing anything wrong here? How can I prevent watchOS2 from calling requestedUpdateDidBegin before I have had a chance to acquire new data from the web?

推荐答案

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

The purpose of transferCurrentComplicationUserInfo is to immediately pass current complication data to the extension. In your code, you are passing settings, however you are not including any weather data.

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

The issue you're seeing stems from trying to asynchronously fetch new data within the extension (which is returning before the data is available).

要解决此问题,您应该基于新设置在手机上获取当前天气数据,然后在当前并发症用户信息中传递(新设置)天气数据.

To handle this, you should fetch the current weather data on the phone based on the new settings, then pass (the new settings along with) the weather data in the current complication user info.

- (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];
    }
}

通过这种方式,并发症服务器可以使用您刚刚传输到手表的当前并发症数据立即更新时间线.

This way, the complication server can immediately update the timeline using the current complication data you just transferred to the watch.

没有过时的数据,没有不必要的第二次更新.

No stale data, no unnecessary second update.

这篇关于如何正确实现将设置从iOS应用转移到watchOS2并发症的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆