updateApplicationContext doesn't always send context

I've noticed that calls to updateApplicationContext() don't always result in func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) being called on the receiving end.


After several days of trial and error it seems the reason is that if the dictionary matches the same as previously passed in it is silently ignored, neither sent nor error thrown.


At first this may seem sensible since it could avoid repeatedly sending the same data due to programmer error. However consider when this is used to pass a shared app state dictionary between watch and iPhone in this basic/contrived example:


  1. Watch calls updateApplicationContext(["THEME_COLOR": "BLUE"]) ---> tells iPhone user has selected a blue theme on the watch, iPhone and watch should honour this choice
  2. iPhone calls updateApplicationContext(["THEME_COLOR": "RED"]) --> User changed their mind, would rather use red theme, iPhone and watch should honour the choice
  3. Watch calls updateApplicationContext(["THEME_COLOR": "BLUE"]) ---> user changes mind again, however this matches the last context update sent from the watch so it's ignored. Watch uses blue theme, iPhone continues to use red theme ERROR!


I can find no documentation stating this will happen. My work around for now is to always add a UUID string to the dictionary to make sure updates to the context are always sent.


Radar: 26001612

Replies

Perform all logic asynchrously when sending and receiving data like this:

     func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {
          dispatch_async(dispatch_get_main_queue(), {
               //YOUR CODE HERE
          })
     }


and


     dispatch_async(dispatch_get_main_queue(), {
          updateApplicationContext(["THEME_COLOR": "BLUE"]) 
     })


Doing it this way fixed all my issues with WatchConnectivity and WCSession

I had a lot of problems with updateApplicationContext not resuting in didReceiveApplicationContext with the iOS 9.3 release. But now, with today's iOS 9.3.2 realease and watchOS 2.2.1, everything looks to be working again. Yay!!!

Excellent point made here! I noticed exactly the same. Calling from the main_queue does not make any difference. Tested this today with iOS 9.3.2 and watchOS 2.2.1. Your workaround: "to always add a UUID string to the dictionary to make sure updates to the context are always sent." solved it for me.


Don't forget to test for (session.activationState == WCSessionActivationStateActivated) before calling updateApplicationContext on the session because according the documentation this is a programmer error: "This method can only be called while the session is active—that is, the

activationState
property is set to
WCSessionActivationStateActivated
. Calling this method for an inactive or deactivated session is a programmer error."