Search code examples
iosswiftwatchkitapple-watchwatchos-2

Why sending message from WatchKit extension to iOS and getting back a reply is so slow?


I am using sendMessage method to send a message from WatchKit extension to an iOS app. It takes about 230 ms on average to receive a reply. The time does not depend on whether the iOS app is on screen or running in the background. 230ms is roughly the time it takes for light to travel the Earth circumference and back. But the phone is sitting 30 cm from my watch when I am testing this.

Questions:

  1. Why is it so slow?
  2. Is it supposed to be so slow?
  3. Is there a way to make it faster?

An observation: according my previous experiments in watchOS 1 communication was a bit faster, a roundtrip used to take about 50 ms.

Send a message from WatchKit extension

let session = WCSession.defaultSession()

session.sendMessage(["message from watch":"🌷"], replyHandler: { reply in
  // Getting reply from iOS app here
}, errorHandler: nil)

Receive the message from iOS app

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {

  replyHandler(["reply from iOS":"🐱"])
}

Demo app: https://github.com/evgenyneu/WatchKitParentAppBenchmark

iOS: 9.0, watchOS: 2.0


Solution

  • AFAIK, when you send a message to other device, the message will be archived to file on local directory that called as WatchDirectory.

    This directory will be synchronized to other device like as other iCloud Drive App or Drop Box through bluetooth. Because this approach doesn't need App running for iOS and watchOS App while the transfer will be finished.

    When the new files were arrived on directory, iOS(or watchOS) will invoke WCSession related API to process content. If needed, iOS(or watchOS) will awake the destination App in background before dispatch message.

    With watchOS1, the watch extension runs on iOS, only remote UI runs on AppleWatch. So it requires much more simple process to communicate, just communication between processes.

    sendMessage is much more expensive method than other communication API those are provided by WCSession. iOS can't use it till the watch App runs foreground, And using sendMessage from watchOS should have to wake up iPhone and launch iOS App in background. After the dispatched messages were handled, iOS may kill the destination app that running on background to get memory back.

    So, IMO there is no reason that it should be fast.