在不运行时保持我的WatchKit并发症是最新的(Keeping my WatchKit complications up to date when not running)
我正在研究我的应用程序的WatchKit扩展,并且有一些并发症的问题。
我有一个复杂功能,显示给定的总金额,这取决于用户在iOS应用程序上做了什么。 当WatchKit扩展程序运行时,iOS应用程序使用
-[WCSession updateApplicationContext:]
方法更新监视应用程序上下文。 它工作正常,然后在我的Watch应用程序的ExtensionDelegate中,我手动更新新数据的复杂性。但只有当扩展程序正在运行时才会出现这种情况(如果不是,则在下次启动之前不会获得应用程序上下文)。
所以我编辑了我的代码,当用户在iOS应用程序中使用
-[WCSession transferCurrentComplicationUserInfo:]
方法更改内容时,将复杂数据直接发送到Watch(它在文档中写入,应该唤醒ExtensionDelegate以接收用户信息)在背景中)。我已经实现了
-session:didReceiveUserInfo:
ExtensionDelegate的方法来在从iOS应用程序接收数据时更新复杂性,但是当扩展未运行时它不起作用...(我不知道是否它曾收到用户信息,因为我无法记录它)即使扩展未运行,我该怎样做才能使我的并发症保持最新?
谢谢
PS:我正在使用Watch Simulator,并且“关闭”扩展我只是重启Watch(从硬件菜单)
编辑 :我设法在应用程序未运行时注销语句(通过打开Watch Simulator系统日志),当iOS将新的复杂用户数据发送到watch扩展时,我得到这些行:
10月18日18:08:11 pc16 WatchApp扩展[26615]:扩展收到唤醒复杂功能支持的请求。
10月18日18:08:11 pc16断言[26585]:断言失败:15A284 13S343:断言+ 15398 [B48FCADB-A071-3A46-878B-538DC0AFF60B]:0x1
因此手表很好地接收了用户信息字典,但似乎无法唤醒扩展...
编辑2 :这是ExtensionDelegate中应该接收复杂用户信息(但在应用程序未运行时未调用)的代码部分:
- (void) session: (WCSession *)session didReceiveUserInfo: (NSDictionary *)userInfo { NSLog(@"session:didReceiveUserInfo: %@", userInfo); NSString *userInfoType = userInfo[KHWASessionTransferUserInfoType]; NSDictionary *userInfoContents = userInfo[KHWASessionTransferUserInfoContents]; // Complication Data if ([userInfoType isEqualToString:KHWASessionTransferUserInfoTypeComplicationData]) { // Store the complication data into user defaults [[NSUserDefaults standardUserDefaults] setValue:userInfoContents[KHWAComplicationTotalBalance] forKey:KHWAComplicationTotalBalance]; [[NSUserDefaults standardUserDefaults] synchronize]; // And refresh the complications CLKComplicationServer *complicationServer = [CLKComplicationServer sharedInstance]; for (CLKComplication *complication in complicationServer.activeComplications) { [complicationServer reloadTimelineForComplication:complication]; } } }
编辑3 :WCSession在扩展委托
applicationDidFinishLaunching
方法中设置:- (void) applicationDidFinishLaunching { // Setup the WatchConnectivity session WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; [...] }
I'm working on the WatchKit Extension of my app, and have some issues with complications.
I have a complication that displays a given total amount, which depends of what the user is doing on the iOS app. When the WatchKit Extension is running, the iOS app updates the watch app context using the
-[WCSession updateApplicationContext:]
method. It works fine, and then in the ExtensionDelegate of my Watch app, I manually update the complication with the new data.But this is OK only when the extension is running (if it's not, it won't get the application context until the next launch).
So I edited my code to send the complication data directly to the Watch when user changed something in the iOS app, using the
-[WCSession transferCurrentComplicationUserInfo:]
method (it's written in the documentation that the ExtensionDelegate should be woken up to receive the user info in background).I've implemented the
-session:didReceiveUserInfo:
method of the ExtensionDelegate to update the complication when it received data from the iOS app, but it doesn't work when the extension is not running... (and I don't know if it ever receives the user info as I can't log it)How should I do to keep my complications up to date even when the extension is not running??
Thanks
PS: I'm using the Watch Simulator, and to "close" the extension I just Reboot the Watch (from the Hardware menu)
Edit: I managed to log out statements when the app is not running (by opening the Watch Simulator system log), and I get these lines when the iOS send a new complication user data to the watch extension:
Oct 18 18:08:11 pc16 WatchApp Extension[26615]: Extension received request to wake up for complication support.
Oct 18 18:08:11 pc16 assertiond[26585]: assertion failed: 15A284 13S343: assertiond + 15398 [B48FCADB-A071-3A46-878B-538DC0AFF60B]: 0x1
So the watch receives well the user info dictionary, but seems to fail waking up the extension...
Edit 2: here is the part of code in the ExtensionDelegate that should receive the complication user info (but which is not called when the app is not running):
- (void) session: (WCSession *)session didReceiveUserInfo: (NSDictionary *)userInfo { NSLog(@"session:didReceiveUserInfo: %@", userInfo); NSString *userInfoType = userInfo[KHWASessionTransferUserInfoType]; NSDictionary *userInfoContents = userInfo[KHWASessionTransferUserInfoContents]; // Complication Data if ([userInfoType isEqualToString:KHWASessionTransferUserInfoTypeComplicationData]) { // Store the complication data into user defaults [[NSUserDefaults standardUserDefaults] setValue:userInfoContents[KHWAComplicationTotalBalance] forKey:KHWAComplicationTotalBalance]; [[NSUserDefaults standardUserDefaults] synchronize]; // And refresh the complications CLKComplicationServer *complicationServer = [CLKComplicationServer sharedInstance]; for (CLKComplication *complication in complicationServer.activeComplications) { [complicationServer reloadTimelineForComplication:complication]; } } }
Edit 3: the WCSession is set in the extension delegate
applicationDidFinishLaunching
method:- (void) applicationDidFinishLaunching { // Setup the WatchConnectivity session WCSession *session = [WCSession defaultSession]; session.delegate = self; [session activateSession]; [...] }
原文:https://stackoverflow.com/questions/33198326