I'm currently playing around with watchOS and communicating with the main iOS App.
The basic and easiest way since watchOS 2 and iOS 9 is to use the
WatchConnectivity Framework provided by Apple.
It's very simple by using the
WCSession instance you can access by
WCSession.default and assign a delegate of the
WCSessionDelegate to it and activate the session on the watchOS and iOS side.
To pass data between the devices, you can use the following methods:
func updateApplicationContext(_ applicationContext: [String : Any]) throws
func sendMessage(_ message: [String : Any], replyHandler: (([String : Any]) -> Void)?, errorHandler: ((Error) -> Void)? = nil)
func sendMessageData(_ data: Data, replyHandler: ((Data) -> Void)?, errorHandler: ((Error) -> Void)? = nil)
The application context is a shared context between the devices and can directly be accessed by the corresponding property of the
Now we get to my use-case: I wanted to transfer the workout-data (heartbeats per minute) from my watch to the phone as fast as possible. I maybe could grab them directly from HealthKit, but I didn't went that way and wanted direct messaging between my Apple Watch and my iPhone.
The second thing I wanted to achieve was to wake up the iOS App when I have data to send from the watch so I don't have to care about that one being launched as well.
To achieve this, you can't use the application context. This only works during runtime. The best way is to use the
sendMessage methods (the data and/or dictionary version depending on your personal use-case).
In my use-case the watchOS-side is sending a dictionary message and triggers the iOS app to wake up and I further analyzed the lifetime on the app side.
I logged when the app
applicationDidBecomeActive, and when my first view controller was loaded and a message received.
This is a regular app launch:
View Controller loaded
App did become active
And this was the log when I send a message from watchOS:
View Controller loaded
The only thing missing was the
applicationDidBecomeActive, but everything else worked as intended and I even got the full first view controller I can work with.
As I was sending messages periodically like every 5 seconds, the app was kept alive for some time, but didn't terminate and also doesn't move to the background, because it already is. Even after some time of not sending any messages. I logged
applicationWillTerminate for this and none of them got triggered.
I hope this information can help some people in designing a code structure for their app without having to run these kind of tests on their own.
This was testet using Xcode 9, iOS 11 and watchOS 4 in Beta 2 and 3