The object that initiates communication between a WatchKit extension and its companion iOS app.
- iOS 9.0+
- Mac Catalyst 13.0+
- watchOS 2.0+
Your iOS app and watchOS app must both create and configure an instance of this class at some point during their execution. When both session objects are active, the two processes can communicate immediately by sending messages back and forth. When only one session is active, the active session may still send updates and transfer files, but those transfers happen opportunistically in the background.
Configuring and Activating the Session
To configure and activate the session, assign a
delegate to the default session object and call that object’s
activate() method, as shown in Listing 1. Your WatchKit extension and iOS app must each configure their own session object. Activating the session establishes a connection between the two apps.
To support the pairing of multiple watches to the same iPhone, the session delegate of both your apps must implement the activation APIs. Implementing the
session(_: method lets the session know that your app supports asynchronous activation. Implementing the
session methods in the session delegate of your iOS app is required to manage transitions between different Apple Watches.
Apps may initiate transfers only when the session is active—that is, the
activation is set to
WCSession. Your iOS app should also check the
is properties before sending any background messages, and it may need to check other properties as needed. Most of the properties you need to check are valid only while the session is active. At other times, the values of the properties may be undefined. The
activation property is always valid and contains the current activation state of the session. For details, see the corresponding property description.
For more information about implementing the methods of the delegate object, see
Supporting Communication with Multiple Apple Watches
An iPhone running iOS 9.3 or later may pair with more than one Apple Watch running watchOS 2.2 or later. In your Watch app, you should support asynchronous activation of the session, but doing so is not required. In your iOS app, you must support asynchronous activation of the session and also monitor the activation and deactivation of the session object. You do this by implementing the following methods in your session delegate:
Figure 1 shows the sequence of events that happen when the user switches from one Apple Watch to another. When automatic switching is enabled, only one Apple Watch at a time actually communicates with the iOS app. The Watch app on each watch stays in the active state, but 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. As soon as that data is delivered, the session moves to the deactivated state. At that point, the iOS app must call the
activate() method again to connect to the newly active watch, which in this example is now the second Apple Watch.
Your iOS app can use the
watch property to store data that is specific to only one instance of your Watch app running on a particular Apple Watch. In most cases, the data you display in each instance of your Watch app is the same. However, you might use this directory to store configuration data, preferences, or other data files that your iOS app needs to interact properly with your Watch app. If you do, use the activation and deactivation process to update your iOS app.
For more information about handling session activation and deactivation, see
Communicating with the Counterpart App
You may initiate data transfers to a counterpart app only when the
activation property is set to
WCSession. The iOS app should ensure the Watch app is installed before trying to initiate transfers. You initiate transfers in any of the following ways:
updatemethod to communicate recent state information to the counterpart. When the counterpart wakes, it can use this information to update its own state. For example, an iOS app that supports Background App Refresh can use part of its background execution time to update the corresponding Watch app. This method overwrites the previous data dictionary, so use this method when your app needs only the most recent data values.
Message(_: reply Handler: error Handler:)
sendmethod to transfer data to a reachable counterpart. These methods are intended for immediate communication between your iOS app and WatchKit extension. The
Message Data(_: reply Handler: error Handler:)
isproperty must currently be
truefor these methods to succeed.
transfermethod to transfer a dictionary of data in the background. The dictionaries you send are queued for delivery to the counterpart and transfers continue when the current app is suspended or terminated.
transfermethod to transfer files in the background. Use this method in cases where you want to send more than a dictionary of values. For example, use this method to send images or file-based documents.
In iOS, use the
transfermethod to send data related to your Watch app’s complication. Use of this method counts against your complication’s time budget.
Current Complication User Info(_:)
When sending messages to a counterpart, background messages are placed on a queue and transmitted in order. Incoming messages are similarly queued and delivered to the delegate in the order in which they were received. Data sent using the
transfer methods has a higher priority and is transmitted right away. All messages received by your app are delivered to the session delegate serially on a background thread.
When sending messages, send only the data that your app needs. All transfers involve sending data wireless to the counterpart app, which consumes power. Rather than sending all of your data every time, send only the items that have changed.
Be prepared to handle errors and provide a graceful fallback when data cannot be transferred. Errors can occur if there is insufficient space for the data on the target device, if the data itself is malformed, or if there is a communications error. Check for errors in your handler code and take appropriate actions.