Apple Watch Connectivity

by

On September 9th, 2014, Tim Cook announced the Apple Watch. This wearable smartwatch quickly gained the loyalty of millions. The wearable was developed in part to incorporate fitness tracking and allow for health tracking, but more-so to free users from their phones. It includes a digital crown used to scroll and zoom, and a touchscreen with Force Touch technology. An extra button under the digital crown serves favorite contacts and access to Apple Pay.

Apple Watch runs on WatchOS and the upgrade to 3.0 allows access to the accelerometer and microphone, and includes the SpriteKit framework used primarily for game development. Currently, the Apple Watch does not support wifi-connectivity. It connects to a paired mobile device via Bluetooth and is able to send and receive data using the Watch Connectivity Framework in WatchOS 2.0.

The Watch Connectivity framework is used to send and receive data between a mobile device and a connected Apple Watch device. The two methods of doing so are:

  • Background Transfers
  • Interactive Messaging

Background transfers are primarily used for sharing data between connected devices when data is not immediately needed on the receiving device. There are three types of background transfers that can be used. The correct type can be determined based on whether the data should be only the latest set of data or all data that has been packaged and not yet been received by the receiver:

  • Application Context – dictionary data used to send only the latest set of data. The container is replaced each time you request to send data.
  • User Information Transfer – dictionary data used to send multiple sets of data. All data is stored in container until system is ready to send data.
  • File Transfer – file type with meta data dictionary used to send multiple files. All data is stored in container until system is ready to send data.

Interactive messaging is used to transfer data immediately between connected devices and requires the Apple Watch app to be in the foreground. In the special case when you are looking to transfer data from the Apple Watch to the mobile device – the app does not need to be in the foreground or background on the mobile device. The Apple Watch sends a notification to the connected mobile device, at which point the app is opened on the mobile device in the background. There are two types of Interactive messaging:

  • Send Message – dictionary type sent immediately
  • Send Message Data – custom data type sent immediately

Before diving into the code, it is important to understand that there is a sender and a receiver. If the sender is the mobile device, then the receiver is the Apple Watch. If the sender is the Apple Watch, then the receiver is the mobile device.

To begin the setup process, we will want to import Watch Connectivity in your mobile application and in your WatchKit Extension:

//Swift:
import WatchConnectivity

You will also want to import WatchKit in your WatchKit Extension if you have any user interface elements:

import WatchKit

You will want to adopt the WatchConnectivitySession Delegate in both your mobile application and in your WatchKit Extension:

//Mobile application:
Class __:UIViewController, WCSessionDelegate


//WatchKit Extension
Class __: WKInterfaceController, WCSessionDelegate

You will now be able to access the WatchConnectivity Delegate methods. Don’t forget to set the delegate otherwise you won’t be able to use them.

In both the mobile application and WatchKit Extension, you will want to create an instance of WCSession, set the delegate, and activate your session. If you need to send data from the Apple Watch to the mobile device, make sure you do this in your App Delegate on the mobile device. If the app opens in the background, any code in the ViewDidLoad, ViewWillAppear, etc will not execute.

let session = WCSession.defaultSession()

self.session.delegate = self
self.session.activateSession()

Depending on the applications needs, you can use these delegate methods to send data.

let context = ["Data":”Sample Data Here”]

//Application Context:
self.session.updateApplicationContext(context)

//User Information Transfer:
self.session.transferUserInfo(context)

//Send Message:
self.session.sendMessage(context, replyHandler: nil, errorHandler: nil)

//File Transfer:
let urlpath = NSBundle.mainBundle().pathForResource("grio-logo-square", ofType: "png")
let url:NSURL = NSURL.fileURLWithPath(urlpath)
let metaData = ["Title":"Grio"]
self.session.transferFile(url, metadata: metaData)

Finally, we have delegate methods on the receiving side that are called when the data is received. Remember to update the UI on the main thread:

//Application Context:
func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {

dispatch_async(dispatch_get_main_queue()) {

//update UI

}

}

//User Information Transfer:
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {

dispatch_async(dispatch_get_main_queue()) {

//update UI

}

}

//Send Message:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject]) {

dispatch_async(dispatch_get_main_queue()) {

//update UI

}

}

//File Transfer:
func session(session: WCSession, didReceiveFile file: WCSessionFile) {
//save in a more permanent location

dispatch_async(dispatch_get_main_queue()) {

let data = NSData.init(contentsOfURL: file.fileURL)
let contentDictionary = file.metadata
//update UI

}

}

Checkout the sample project on Github:
https://github.com/arpadhani/WatchOS2-Watch-Connectivity

Leave a Reply

Your email address will not be published. Required fields are marked *