Communicating with WCSession
WatchKit on watchOS 2 brings major improvements to how Apple Watch apps communicate with their host app. Gone is openParentApplication(_:reply:), which has been replaced by the more capable WCSession.
WCSession allows WatchKit apps and their counterpart application to communicate, bidirectionally, in three ways: an updatable Application Context, live messages, and background transfers. The two later communication methods can either send a dictionary of values or raw data.
Application Context #
The Application Context is a dictionary that’s sent to the counterpart and persisted. The dictionary can then be read when the counterpart, whether that’s the WatchKit app or the host app, wakes up.
Updating the Application Context is simple. Just call updateApplicationContext(_:). This replaces the prior context value visible to the counterpart application. Note that
updateApplicationContext(_:) will throw (in Swift) if communication with the counterpart device fails or if you attempt to send non-property-list datatypes.
You can see what you last sent to your counterpart by examining the applicationContext property. Similarly, you can examine receivedApplicationContext to read the last state received from the counterpart. The Application Context is probably best used for bits of state that should be kept in sync between the two apps (e.g. syncing timeline state, the id of the selected user, and so on).
Sending Messages #
Two methods to send messages and optionally receive a reply are also provided. Their behavior is similar to how
You can send a dictionary with sendMessage(_:replyHandler:errorHandler:). Multiple messages will be queued and delivered serially.
The second method provided is
sendMessageData(_:replyHandler:errorHandler:), which lets you send data between devices, as you might have guessed.
In either case, the host iPhone app will be started in the background when a message is received if you send from a WatchKit app to iPhone. Sending a message in the other direction will not start your WatchKit app.
Transferring Files and Data in the Background #
Two additional methods, transferUserInfo(_:) and transferFile(_:), allow you to send dictionary or file data, respectively, in the background. These methods do not wake up the host iPhone app and delivery could be throttled due to power constraints.
A property corresponding to each of these lets you list and cancel pending dictionary or file transfers. See outstandingUserInfoTransfers and outstandingFileTransfers for more information.
Handling and Responding with WCSessionDelegate #
You should implement WCSessionDelegate to handle and/or respond to WCSession events. You can implement methods corresponding to the communication method you employ in your counterpart app. Read the documentation for details. One important thing to note is these delegate methods are called on a background queue so don’t forget to dispatch to the main queue if you intend to update your user interface.
WWDC Video #
Introducing WatchKit Connectivity goes over WCSession in detail. I suggest watching it before digging in.