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];
[...]
}
Wow, I finally resolved the issue!
It seems that, even if I didn't see it in the log files (see my last comment), the init
method of WCExtensionDelegate is well called when waking up the app.
So I just had to move the WCSession setting bloc into the init
method :
- (id) init
{
if (self = [super init]) {
// Setup the WatchConnectivity session
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
}
return self;
}
And for the while it works fine...
来源:https://stackoverflow.com/questions/33198326/keeping-my-watchkit-complications-up-to-date-when-not-running