WWDC 2015

Introduction to Watch Connectivity

From WatchOS 1, there are only limited ways to communicate between Apple Watch and iPhone. In WatchOS2 , Watch Connectivity framework enables third-party developers to have better options to send and receive data from Watch. Additional safe guards are provided to check if the connectivity is available and well-established.

Setup

//check if the device supports Watch Connectivity (iPhone supports but iPad does not)
if (WCSession.isSupported()) { 
    let session = WCSession.defaultSession()
    session.delegate = self
    sesssion.activateSession()
} 

//WCSessionDelegate methods 
//called whenever the session had changed
func sessionWatchStateDidChange(_ session: WCSession) {
    //use this to check if the watch and iPhone are paired
    if ( session.paired ) {
        ...
    }

    //check if the watch has installed the watch app 
    if ( session.watchAppInstalled ) {
        ...
    }

    //watchDirectoryURL is not nil if the watch has installed the watch app 
    if let session.watchDirectoryURL {
    } 

    //check if the complication is enabled on watch face
    if (session.complicationEnabled ) {
    }
}

Communication

Background transfers

  • Content not needed immediately
  • OS intelligently transfers content
  • The message will be queue up
  • OS pick the opportune time for sending
  • Delievers when the receiver app is launched

Types

  • Application context
    • most interesting/ relvent content to deliver
    • Overriding behavior
    • In Dictionary
    • Not in main thread
    • Recommend to use in Most watch app and glance
      //sending 
      do {
        let context = // Create context dictionary with latest state
        try WCSession.defaultSession().updateApplicationContext(context)
      } catch {
      // Handle any errors
      }
      //receiving
      func session(session: WCSession, didReceiveApplicationContext:
            applicationContext: [String : AnyObject]) {
        // Handle application context dictionary
      }
      
  • User Info content
    • information about user info like game level completions and inform iPhone or starting a location
    • In Dictionary
    • Not on main thread
    • on outstanding queue on sender
    • Cancel as nedded
//Sending
let userInfo = // Create dictionary of userInfo
//get transfer object for cancelling
let userInfoTransfer = WCSession.defaultSession().transferUserInfo(userInfo)
//Check outstanding items for transferring
let transfers = WCSession.defaultSession().outstandingUserInfoTransfers()
//Reciving
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
    // Handle incoming user info dictionary
}
  • File Transfer
    • Similar to user info transfer but transferring files
    • Provided metadata for accompanying the file URL
    • Must move files to app's space as the inbox of receiver will be clean up once the transfer is finsihed
//Sending
let url = // Retrieve URL of file
let metadata = // Create dictionary of metadata
let fileTransfer = WCSession.defaultSession().transferFile(url,
metadata:metadata)
//Outstanding queue
let transfers = WCSession.defaultSession().outstandingFileTransfers()
// Receiver Callback
func session(session: WCSession, didReceiveFile file: WCSessionFile) {
   // Handle file URL and metadata in WCSessionFile object
 }

Interactive messaging

  • Live communication

    • iPhone app in background
    • Watch app must be foreground
    • Devices are connected
    • use session.reachable to check if the interactive messaging is available
    • Types
      • Plist
        func sendMesage(message:, replyHandler:, errorHandler:)
        
      • Data (custom data or own serialization)
        func sendMessageData(data:, replyHandler:, errorHandler:)
        
  • Optional handler used for confirmation by receiver

  • separate delegate callbacks with/ without handler
func session(session: WCSession, didReceiveMessage message: [String :
AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    // Handle message, return reply
}
func session(session: WCSession, didReceiveMessage message: [String :
AnyObject]) {
    // Handle message
}

NSURLSession

  • requires instant / new content
  • Content is tailor-made to watch in terms of smaller size or more concise
  • Usage : Complication
    • fetch content via NSURLSession while WatchKit Extension in the background
    • Register via PushKit and set desiredPushTypes as [PKPushTypeComplication]
    • Upload the push token to the server
    • receiver push payload via didReceiveIncomingPushWithPayload to transfer timeLineEntry to the watch
    • session.transferCurrentComplicationUserInfo(presentTimeLineEntry) to transfer
    • func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) to handle the receiver and update complication