2

I'm developing a WatchApp that needs to communicate with the iOS App and I'm using the Watch Connectivity fwk to do that.

Each time the user displays my WatchApp I need to get from the iOS App a new set of data that must be displayed on the Watch.

To get these data I'm using sendMessage(_:replyHandler:errorHandler:) but sometimes it seems this communication is not working because my WatchApp is not updated. I have no issue when the WatchApp has been started from Xcode, issues appear only when I'm using it in the real life.

I trigger the synchronization between the WatchApp and the iOS App each time my WatchApp is callback on:

  • WKInterfaceController.willActivate() (I have only one Controller)
  • WCSessionDelegate.session(WCSession, didReceiveApplicationContext:
    [String : Any])
    when the activationState == .activated
  • WCSessionDelegate.sessionReachabilityDidChange(WCSession) when the
    session is reachable

In the video "Introducing Watch Connectivity" for the 2015 WWDC, the speaker tells the WatchKit Extension must be running foreground when sending an interactive message to the iOS App.

Does it mean I need to check the WKExtention.shared().applicationState == .active before to call sendMessage(_:replyHandler:errorHandler:), in addition of WCSession.activationState == .activated ?

When my WatchApp is in the Dock and the user displays the Dock, my WatchApp has a WKExtension.shared().applicationState == .inactive and WKExtension.shared().isApplicationRunningInDock == true, Can I use sendMessage(_:replyHandler:errorHandler:) to update my App in this state?

I'm just wondering which conditions I need to check before to use sendMessage(_:replyHandler:errorHandler:).

Thanks,

sebastien
  • 2,489
  • 5
  • 26
  • 47

1 Answers1

0

When i send watch connectivity messages I always check session.activationState == .activated && session.isReachable. Also I usually send an initial message and wait for the phone to respond before requesting data. This seems to make responses more reliable than requesting data initially for some reason. Here is an example

func sendActivationMessage() {
    if session.activationState == .activated && session.isReachable {
        session.sendMessage(["Watch Message" : "Activate"], replyHandler: { (reply) in

            // Send message requesting data

        }, errorHandler: { (error) in

            print("***** Error Did Occur: \(error) *****")
        })
    } else {
        print("***** Activation Error *****")
    }
}

If print("***** Activation Error *****") gets called then you know that the phone is not reachable.

Zachary Bell
  • 559
  • 4
  • 18
  • Thanks for the reply! Based on my latest experience I don't think it's sufficient to test activationState and isReachable because it can happen that the session is activated and reachable but the WatchApp is running background (WKExtension applicationState != active). sendMessage(replyHandler:error:) is for interactive message and it supposes the WatchApp is running foreground (my understanding from WWDC video). I have done the change, to check the WatchApp is foreground before to sendMessage() and it seems working well since more than 24h. Wait and see... – sebastien Nov 06 '17 at 19:24