<!--
{
  "availability" : [
    "iOS: 9.0.0 -",
    "iPadOS: 9.0.0 -",
    "macCatalyst: 9.0.0 -",
    "visionOS: 1.0.0 -",
    "watchOS: 2.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "WatchConnectivity",
  "identifier" : "/documentation/WatchConnectivity/WCSession",
  "metadataVersion" : "0.1.0",
  "role" : "Class",
  "symbol" : {
    "kind" : "Class",
    "modules" : [
      "Watch Connectivity"
    ],
    "preciseIdentifier" : "c:objc(cs)WCSession"
  },
  "title" : "WCSession"
}
-->

# WCSession

The object that initiates communication between a WatchKit extension and its companion iOS app.

```
class WCSession
```

## Overview

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.

> Important:
> The session object must be configured and activated before you attempt to send messages or obtain information about the state of the connection. Before activating the session, you may call the ``doc://com.apple.watchconnectivity/documentation/WatchConnectivity/WCSession/isSupported()`` method to make sure that current device can use the Watch Connectivity framework.

### Configuring and Activating the Session

To configure and activate the session, assign a [`delegate`](/documentation/WatchConnectivity/WCSession/delegate) to the default session object and call that object’s [`activate()`](/documentation/WatchConnectivity/WCSession/activate()) method, as shown in code snippet below. Your WatchKit extension and iOS app must each configure their own session object. Activating the session establishes a connection between the two apps.

```swift
if WCSession.isSupported() {
   let session = WCSession.default
   session.delegate = self
   session.activate()
}
```

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(_:activationDidCompleteWith:error:)`](/documentation/WatchConnectivity/WCSessionDelegate/session(_:activationDidCompleteWith:error:)) method lets the session know that your app supports asynchronous activation. Implementing the [`sessionDidBecomeInactive(_:)`](/documentation/WatchConnectivity/WCSessionDelegate/sessionDidBecomeInactive(_:)) and [`sessionDidDeactivate(_:)`](/documentation/WatchConnectivity/WCSessionDelegate/sessionDidDeactivate(_:)) methods in the session delegate of your iOS app is required to manage transitions between different Apple Watches.

> Important:
> If your delegate does not implement the appropriate methods for asynchronous activation and activation state changes, your app opts out of multiple Apple Watch support altogether. Opting out has important implications for your app when the user switches from one Apple Watch to another. When a switch occurs, your app’s session is deactivated. When your app subsequently moves to the background, the system terminates your app. (Background execution modes do not prevent the termination of your app.) The next time your app launches, it connects with the new Apple Watch.

Apps may initiate transfers only when the session is active—that is, the [`activationState`](/documentation/WatchConnectivity/WCSession/activationState) is set to [`WCSessionActivationState.activated`](/documentation/WatchConnectivity/WCSessionActivationState/activated). Your iOS app should also check the [`isPaired`](/documentation/WatchConnectivity/WCSession/isPaired) and [`isWatchAppInstalled`](/documentation/WatchConnectivity/WCSession/isWatchAppInstalled) 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 [`activationState`](/documentation/WatchConnectivity/WCSession/activationState) 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 [`WCSessionDelegate`](/documentation/WatchConnectivity/WCSessionDelegate).

### 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:

- [`session(_:activationDidCompleteWith:error:)`](/documentation/WatchConnectivity/WCSessionDelegate/session(_:activationDidCompleteWith:error:))
- [`sessionDidBecomeInactive(_:)`](/documentation/WatchConnectivity/WCSessionDelegate/sessionDidBecomeInactive(_:))
- [`sessionDidDeactivate(_:)`](/documentation/WatchConnectivity/WCSessionDelegate/sessionDidDeactivate(_:))

[Figure 1](/documentation/watchconnectivity/wcsession#1965795) 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()`](/documentation/WatchConnectivity/WCSession/activate()) method again to connect to the newly active watch, which in this example is now the second Apple Watch.

![](images/com.apple.watchconnectivity/media-1965795@2x.png)

Your iOS app can use the [`watchDirectoryURL`](/documentation/WatchConnectivity/WCSession/watchDirectoryURL) 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 [`WCSessionDelegate`](/documentation/WatchConnectivity/WCSessionDelegate).

### Communicating with the Counterpart App

You may initiate data transfers to a counterpart app only when the [`activationState`](/documentation/WatchConnectivity/WCSession/activationState) property is set to [`WCSessionActivationState.activated`](/documentation/WatchConnectivity/WCSessionActivationState/activated). The iOS app should ensure the Watch app is installed before trying to initiate transfers. You initiate transfers in any of the following ways:

- Use the [`updateApplicationContext(_:)`](/documentation/WatchConnectivity/WCSession/updateApplicationContext(_:)) method 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.
- Use the [`sendMessage(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessage(_:replyHandler:errorHandler:)) or [`sendMessageData(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessageData(_:replyHandler:errorHandler:)) method to transfer data to a reachable counterpart. These methods are intended for immediate communication between your iOS app and WatchKit extension. The [`isReachable`](/documentation/WatchConnectivity/WCSession/isReachable) property must currently be <doc://com.apple.documentation/documentation/Swift/true> for these methods to succeed.
- Use the [`transferUserInfo(_:)`](/documentation/WatchConnectivity/WCSession/transferUserInfo(_:)) method 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.
- Use the [`transferFile(_:metadata:)`](/documentation/WatchConnectivity/WCSession/transferFile(_:metadata:)) method 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 [`transferCurrentComplicationUserInfo(_:)`](/documentation/WatchConnectivity/WCSession/transferCurrentComplicationUserInfo(_:)) method to send data related to your Watch app’s complication. Use of this method counts against your complication’s time budget.

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 [`sendMessage(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessage(_:replyHandler:errorHandler:)), [`sendMessageData(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessageData(_:replyHandler:errorHandler:)), and [`transferCurrentComplicationUserInfo(_:)`](/documentation/WatchConnectivity/WCSession/transferCurrentComplicationUserInfo(_:)) 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.

> Note:
> Remember that background transfers are not delivered immediately. The system sends data as quickly as possible but transfers are not instantaneous, and the system may delay transfers slightly to improve power usage. Also, sending a large data file requires a commensurate amount of time to transmit the data to the other device and process it on the receiving side.

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.

## Topics

### Getting the Default Session

[`isSupported()`](/documentation/WatchConnectivity/WCSession/isSupported())

Returns a Boolean value indicating whether the current iOS device is able to use a session object.

[`default`](/documentation/WatchConnectivity/WCSession/default)

Returns the singleton session object for the current device.

### Configuring the Session

[`delegate`](/documentation/WatchConnectivity/WCSession/delegate)

The delegate for the session object

[`activate()`](/documentation/WatchConnectivity/WCSession/activate())

Activates the session asynchronously.

[`activationState`](/documentation/WatchConnectivity/WCSession/activationState)

The current activation state of the session.

### Getting the Paired Device Information

[`isPaired`](/documentation/WatchConnectivity/WCSession/isPaired)

A Boolean indicating whether the current iPhone has a paired Apple Watch.

[`iOSDeviceNeedsUnlockAfterRebootForReachability`](/documentation/WatchConnectivity/WCSession/iOSDeviceNeedsUnlockAfterRebootForReachability)

A Boolean value indicating whether the paired iPhone must be in an unlocked state to be reachable.

[`isWatchAppInstalled`](/documentation/WatchConnectivity/WCSession/isWatchAppInstalled)

A Boolean value indicating whether the currently paired and active Apple Watch has installed the app.

[`isCompanionAppInstalled`](/documentation/WatchConnectivity/WCSession/isCompanionAppInstalled)

A Boolean value indicating whether the companion has installed the app.

[`isComplicationEnabled`](/documentation/WatchConnectivity/WCSession/isComplicationEnabled)

A Boolean value indicating whether the Watch app’s complication is in use on the currently paired and active Apple Watch.

[`watchDirectoryURL`](/documentation/WatchConnectivity/WCSession/watchDirectoryURL)

A directory for storing information specific to the currently paired and active Apple Watch.

### Determining the Session’s Reachability

[`isReachable`](/documentation/WatchConnectivity/WCSession/isReachable)

A Boolean value indicating whether the counterpart app is available for live messaging.

### Managing Background Updates

[`updateApplicationContext(_:)`](/documentation/WatchConnectivity/WCSession/updateApplicationContext(_:))

Sends a dictionary of values that a paired and active device can use to synchronize its state.

[`applicationContext`](/documentation/WatchConnectivity/WCSession/applicationContext)

The most recent contextual data sent to the paired and active device.

[`receivedApplicationContext`](/documentation/WatchConnectivity/WCSession/receivedApplicationContext)

A dictionary containing the last update data received from a paired and active device.

### Sending Messages

[`sendMessage(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessage(_:replyHandler:errorHandler:))

Sends a message immediately to the paired and active device and optionally handles a response.

[`sendMessageData(_:replyHandler:errorHandler:)`](/documentation/WatchConnectivity/WCSession/sendMessageData(_:replyHandler:errorHandler:))

Sends a data object immediately to the paired and active device and optionally handles a response.

### Updating Complication Data

[`remainingComplicationUserInfoTransfers`](/documentation/WatchConnectivity/WCSession/remainingComplicationUserInfoTransfers)

The number of remaining times you can send complication data from the iOS app to the WatchKit extension.

[`transferCurrentComplicationUserInfo(_:)`](/documentation/WatchConnectivity/WCSession/transferCurrentComplicationUserInfo(_:))

Sends complication-related data from the iOS app to the WatchKit extension.

### Transferring Data in the Background

[`transferUserInfo(_:)`](/documentation/WatchConnectivity/WCSession/transferUserInfo(_:))

Sends the specified data dictionary to the counterpart.

[`outstandingUserInfoTransfers`](/documentation/WatchConnectivity/WCSession/outstandingUserInfoTransfers)

An array of in-progress data transfers.

### Transferring Files in the Background

[`transferFile(_:metadata:)`](/documentation/WatchConnectivity/WCSession/transferFile(_:metadata:))

Sends the specified file and optional dictionary to the counterpart.

[`outstandingFileTransfers`](/documentation/WatchConnectivity/WCSession/outstandingFileTransfers)

An array of in-progress file transfers.

[`hasContentPending`](/documentation/WatchConnectivity/WCSession/hasContentPending)

A Boolean value that indicates whether the session has more content to deliver.

### Constants

[`WCSessionActivationState`](/documentation/WatchConnectivity/WCSessionActivationState)

Constants indicating the activation state of a session.

[`WCErrorDomain`](/documentation/WatchConnectivity/WCErrorDomain)

The domain for errors associated with the Watch Connectivity framework.

[`WCError`](/documentation/WatchConnectivity/WCError)

A structure that contains Watch Connectivity error information.

[`WCError.Code`](/documentation/WatchConnectivity/WCError/Code)

Constants for errors during a session.



---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)