WatchConnectivity sendMessageData slowness

Hi,


I'm experimenting with controlling some UI widgets in an iPhone app through the digital crown with WatchOS 2. In the watch extension I get the WKPicker value changes nice and smoothly, which I can track through debug statements. However, when I use sendMessageData there's a long delay before the iPhone app receives the data. Worse even, this seems to be all put into a queue that is serviced at a fixed (slow) interval rate, so if you send a series of messages (like rotating the digital crown), you can see the iPhone app receiving messages seconds after the action happens.


Here's the simple snippet I use in the extension.


- (IBAction)pickerValueChanged:(int)value {
    NSLog(@"%s %d", __FUNCTION__, value);
    NSData *data = [NSData dataWithBytes:&value length:sizeof(int)];
    [[WCSession defaultSession] sendMessageData:data replyHandler:nil errorHandler:nil];
}

In the iPhone app I simply do:


    if ([WCSession isSupported]) {
        WCSession* session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }


and:


- (void)session:(WCSession *)session didReceiveMessageData:(NSData *)messageData {
    int value;
    [messageData getBytes:&value length:sizeof(int)];
    NSLog(@"%s %d", __FUNCTION__, value);
}


The output of the watch extension is for example like this, you can clearly see that the values are updated with only 10ths of milliseconds between them:


2015-07-11 08:56:09.213 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 1
2015-07-11 08:56:09.247 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 2
2015-07-11 08:56:09.265 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 3
2015-07-11 08:56:09.281 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 5
2015-07-11 08:56:09.298 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 8
2015-07-11 08:56:09.314 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 11
2015-07-11 08:56:09.330 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 13
2015-07-11 08:56:09.347 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 15
2015-07-11 08:56:09.365 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 17
2015-07-11 08:56:09.380 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 19
2015-07-11 08:56:09.397 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 20
2015-07-11 08:56:09.414 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 22
2015-07-11 08:56:09.430 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 23
2015-07-11 08:56:09.447 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 24
2015-07-11 08:56:09.464 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 25
2015-07-11 08:56:09.480 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 26
2015-07-11 08:56:09.498 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 27
2015-07-11 08:56:09.514 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 28
2015-07-11 08:56:09.531 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 29
2015-07-11 08:56:09.564 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 30
2015-07-11 08:56:09.648 Watch Extension[27015:277853] -[InterfaceController pickerValueChanged:] 31


That value sent over to the iPhone app with sendMessageData, results into this output:


2015-07-11 08:56:09.421 App iPhone[27043:279391] -[iosAppDelegate session:didReceiveMessageData:] 1
2015-07-11 08:56:09.614 App iPhone[27043:279391] -[iosAppDelegate session:didReceiveMessageData:] 2
2015-07-11 08:56:09.825 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 3
2015-07-11 08:56:10.025 App iPhone[27043:279404] -[iosAppDelegate session:didReceiveMessageData:] 5
2015-07-11 08:56:10.227 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 8
2015-07-11 08:56:10.431 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 11
2015-07-11 08:56:10.631 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 13
2015-07-11 08:56:10.830 App iPhone[27043:279391] -[iosAppDelegate session:didReceiveMessageData:] 15
2015-07-11 08:56:11.036 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 17
2015-07-11 08:56:11.233 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 19
2015-07-11 08:56:11.430 App iPhone[27043:278482] -[iosAppDelegate session:didReceiveMessageData:] 20
2015-07-11 08:56:11.643 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 22
2015-07-11 08:56:11.643 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 22
2015-07-11 08:56:11.644 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 23
2015-07-11 08:56:12.743 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 24
2015-07-11 08:56:12.743 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 25
2015-07-11 08:56:12.744 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 26
2015-07-11 08:56:12.744 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 27
2015-07-11 08:56:12.744 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 24
2015-07-11 08:56:12.745 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 25
2015-07-11 08:56:12.745 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 26
2015-07-11 08:56:12.745 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 27
2015-07-11 08:56:12.746 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 28
2015-07-11 08:56:12.746 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 24
2015-07-11 08:56:12.746 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 25
2015-07-11 08:56:12.746 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 26
2015-07-11 08:56:12.746 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 27
2015-07-11 08:56:12.747 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 28
2015-07-11 08:56:12.747 App iPhone[27043:279396] -[iosAppDelegate session:didReceiveMessageData:] 29
2015-07-11 08:56:13.842 App iPhone[27043:279391] -[iosAppDelegate session:didReceiveMessageData:] 30
2015-07-11 08:56:13.843 App iPhone[27043:279391] -[iosAppDelegate session:didReceiveMessageData:] 31


Where the interval between the values seems to be hundreds of millisecond. The whole sequence completes in over 4 seconds, while on the extension it took 400 ms. Additionally, some values seem to be repeated and coming in out of order.


Both the extension and the app run on the iPhone, using WCSession, I don't understand why the slowness is there nor why it would be needed.


Any ideas about how to improve this? Anything I'm doing wrong?


Thanks for the help,


Geert

Hi,


The out of order-ness sounds like a bug. Could you please file a bug, include a small sample project and reply back here with the radar number?


As for the performance, some delay is to be expected. In this case I'd suggest either restricting the frequency in which you send the messages to a couple per second or building a method of "back pressure" on top of send message with reply.

Hi Viking,


Thanks for your reply. I would expect some delay between the Watch and the iPhone App Extension, but this is not where the trouble lies. The delay I refer to lies between the App Extension and the actual iPhone app, both running on the same device. Also, this is not just 'some' delay, one message per 200ms is amazingly slow queue handling. I can't really restrict the frequency of updates, since the whole point would be to use the nice feel of the digital crown to articulate aspects of the iPhone app in real time, speed and fine-grained detailed control are critical. Finally, sending 21 messages in 430ms should not really be 'high pressure', certainly not on the same device. This really feels to me like conscious throttling of the message queue between the App Extension and the App, but in a way that prohibits many interesting use-cases.


Take care,


Geert

Accepted Answer

Hi Geert,


Thanks for getting back to me. You are right that in watchOS 1 your WatchKit extension and iOS app were both running on the same device (iPhone); however in watchOS 2 the WatchKit extension has moved over to the watch (this and lots more information is available in the watchOS 2 Transition Guide).


The messages you send using WatchConnectivity is not just IPC on the same device; it is actually bytes wirelessly being transmitted between your WatchKit extension running on the watch and your iOS app on the phone. The extension running on the watch means that your app will be much more responsive, and also can function even when the phone is not around/powered down. It does however have the caveat that you no longer can rely on a shared data container, etc.

The WWDC WatchConnectivity session briefly discusses the architecture change, and then goes on to provide lots of great advice on how to best use the framework.

Thanks a lot Viking, this is very useful and I'm sorry that I didn't pay proper attention to the transition guide. I'll read through it in more detail now. The WWDC session looks very interesting too.

WatchConnectivity sendMessageData slowness
 
 
Q