WatchConnectivity and App Lifetime
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 WCSession
instance.
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 didFinishLaunchingWithOptions
, applicationDidBecomeActive
, and when my first view controller was loaded and a message received.
This is a regular app launch:
App launched
View Controller loaded
App did become active
And this was the log when I send a message from watchOS:
App launched
View Controller loaded
got message
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 applicationWillResignActive
, applicationDidEnterBackground
and 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