Search code examples
ioswatchoswatchconnectivitywcsessionios9.3

How to support multiple watches for iOS 9.3 and watchOS 2.2


Having trouble figuring out how to update my watch and iOS apps for watchOS 2.2 in order to support multiple watches.

I know there are new functions that must be implemented primarily on the iOS app side, but also on the watch extension according to the Developer Library:

session:activationDidCompleteWithState:error:

sessionDidBecomeInactive:

sessionDidDeactivate:

I'm not really sure how to do it and what code these functions should run.


Solution

  • An iPhone running iOS 9.3 or later may pair with more than one Apple Watch running watchOS 2.2 or later.

    All three WCSessionDelegate methods are required on iOS to support asynchronous session activation required for quick watch switching.

    Switching from a watch:

    When automatic switching is enabled, and the user switches from one Apple Watch to another, the iOS app moves to the inactive and deactivated states during a switch.

    Moving to the inactive state gives the session a small amount of time to deliver any data that has already been received.

    // MARK: WCSessionDelegate - Asynchronous Activation
    // The next 3 methods are required in order to support asynchronous session activation; required for quick watch switching.
    
    func sessionDidBecomeInactive(session: WCSession) { // iOS only
        /*
            The session calls this method when it detects that the user has
            switched to a different Apple Watch. While in the inactive state,
            the session delivers any pending data to your delegate object and
            prevents you from initiating any new data transfers. After the last
            transfer finishes, the session moves to the deactivated state.
    
            Use this method to update any private data structures that might be
            affected by the impending change to the active Apple Watch. For example,
            you might clean up data structures and close files related to
            outgoing content.
         */
    
        print("session did become inactive")
    }
    

    As soon as that data is delivered, the session moves to the deactivated state. At that point, the iOS app must call the activateSession method again to connect to the newly active watch.

    func sessionDidDeactivate(session: WCSession) { // iOS only
        print("session did deactivate")
    
        /*
            The session calls this method when there is no more pending data
            to deliver to your app and the previous session can be formally closed.
    
            iOS apps that process content delivered from their Watch Extension
            should finish processing that content, then call activateSession()
            to initiate a session with the new Apple Watch.
         */
    
        // Begin the activation process for the new Apple Watch
        WCSession.defaultSession().activateSession()
    }
    

    Switching to a watch:

    Both iOS and watchOS apps would implement the following method to be called once their WCSession is activated:

    func session(session: WCSession, activationDidCompleteWithState activationState: WCSessionActivationState, error: NSError?) {
        if let error = error {
            print("session activation failed with error: \(error.localizedDescription)")
            return
        }
    
        /*
            Called when the activation of a session finishes. Your implementation
            should check the value of the activationState parameter to see if
            communication with the counterpart app is possible. When the state is
            WCSessionActivationStateActivated, you may communicate normally with
            the other app.
         */
    
        print("session activated with state: \(activationState.rawValue)")
    }
    

    Sample Code:

    Apple has provided QuickSwitch sample code to demonstrate proper use of the WatchConnectivity framework in order to support quick watch switching with multiple Apple Watches. It uses updateApplicationContext to pass a designator and color from a paired watch to the phone.

    Other notes:

    An unconnected watch app can continue to use all transfer methods including interactive messaging (although outgoing data does get queued by the system, and is not transferred until the user switches back to that watch).

    For further details, see How can watchOS 2.2 app determine if its paired iPhone has switched to another Apple Watch?

    Credits:

    Provided code is based on QuickSwitch, and details found in the WCSessionDelegate Protocol Reference, and WCSession Class Reference, under Supporting Communication with Multiple Apple Watches.