<!--
{
  "documentType" : "article",
  "framework" : "AccessoryTransportExtension",
  "identifier" : "/documentation/AccessoryTransportExtension/accessory-features",
  "metadataVersion" : "0.1.0",
  "role" : "collectionGroup",
  "title" : "Accessory features"
}
-->

# Accessory features

Declare and handle the features that carry data between your accessory and your app.

## Overview

With the exception of Wi-Fi network sharing, every scenario Accessory Transport Extension supports for moving data between a connected accessory and an iPhone relies on the *feature* model. You implement an [`AccessoryDataProvider`](/documentation/AccessoryTransportExtension/AccessoryDataProvider) extension that declares the features you support, and the system routes each feature’s data to the handler you write. Each session is scoped to one feature. The framework defines the complete set of features, and you can’t add your own, though a worker feature lets you carry data in a format your app defines.

Other frameworks extend the feature model to add their own features. The exception is the accessory worker and accessory GPU worker, which the Accessory Transport Extension framework defines directly:

- Notification forwarding: Delivers iOS system notifications to your accessory. See <doc://com.apple.documentation/documentation/AccessoryNotifications/NotificationsForwarding> and [Receiving iOS notifications on an accessory](/documentation/AccessoryTransportExtension/receiving-ios-notifications-on-an-accessory).
- Live Activity forwarding: Delivers Live Activity status updates and alerts to your accessory. See <doc://com.apple.documentation/documentation/AccessoryLiveActivities/LiveActivityForwarding>.
- Audio accessory head tracking: Forwards head-position sensor data from an audio accessory you develop to the system’s spatial audio renderer. See <doc://com.apple.documentation/documentation/AudioAccessoryKit/AudioAccessoryHeadTracking>.
- Accessory worker: Carries data in a format your app defines between your data provider and transport extensions. See [`AccessoryWorker`](/documentation/AccessoryTransportExtension/AccessoryWorker) and [Sending data to an accessory in the background](/documentation/AccessoryTransportExtension/sending-data-to-an-accessory-in-the-background).
- Accessory GPU worker: Carries data, like an accessory worker, under a sandbox profile that permits GPU access. See [`AccessoryGPUWorker`](/documentation/AccessoryTransportExtension/AccessoryGPUWorker).

For a framework-defined feature, such as notification forwarding, the system starts the session. For example, an incoming iOS system notification starts a notification-forwarding session without a call from your app.

Worker features differ from framework-defined features in two ways. Your app defines the format for both sending and receiving, and your transport extension starts every session in response to an event from your accessory. Enroll a worker feature for each accessory by calling `AccessoryWorker/requestAuthorization(for:)`. When your app enrolls a feature, the enrollment takes effect immediately without prompting the person. An enrolled features stays enrolled for the life of the accessory’s pairing. Other features use the authorization flow of their owning framework.

## Declare a feature

To use a feature:

1. Add the feature’s identifier to your data provider extension’s `EXCapabilities` key.
2. Declare the feature in your extension’s `extensionPoint` body with a closure that creates your handler.
3. Implement the handler to respond to the feature’s events.
4. For a worker feature, enroll the feature for the accessory from your app during initial pairing with <doc://com.apple.documentation/documentation/AccessorySetupKit>, or from your transport extension, and then open the session from your transport extension.

> Note: The `EXCapabilities` key is the feature’s ``doc://com.apple.accessorytransportextension/documentation/AccessoryTransportExtension/AccessoryFeature/featureID``; it differs from ``doc://com.apple.accessorytransportextension/documentation/AccessoryTransportExtension/TransportMessage/sessionID``, a UUID that your transport extension reads to discern which feature an incoming message belongs to for a paired accessory. The data provider’s ``doc://com.apple.accessorytransportextension/documentation/AccessoryTransportExtension/AccessoryFeatureSession/sessionID`` shares that value.

## Open a worker feature session

A feature session carries data for a single feature. It’s distinct from the [`AccessoryTransportSession`](/documentation/AccessoryTransportExtension/AccessoryTransportSession) that connects your transport extension to the system for one accessory. Every feature defines a capability that conforms to [`AccessoryFeatureSession`](/documentation/AccessoryTransportExtension/AccessoryFeatureSession), and is launched in the data provider. Worker features also utilize a transport extension, which conforms to [`AccessoryFeatureRuntimeSession`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSession). For the other features, the system delivers data to your transport extension through [`messageReceived(_:completion:)`](/documentation/AccessoryTransportExtension/AccessoryTransportSession/EventHandler/messageReceived(_:completion:)).

To open the data provider’s feature session, call [`makeFeatureSession(_:)`](/documentation/AccessoryTransportExtension/AccessoryTransportSession/makeFeatureSession(_:)) from your transport extension when your accessory reports a change, then call [`activate()`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSession/activate()). The system permits one live session per feature for each accessory. For more information on worker features, see [Sending data to an accessory in the background](/documentation/AccessoryTransportExtension/sending-data-to-an-accessory-in-the-background).

## Confirm the start of a session

The system calls [`sessionStarted(_:)`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSessionHandler/sessionStarted(_:)) once your feature session is ready to run.

Returning from [`activate()`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSession/activate()) doesn’t mean the session started. If your app hasn’t enrolled the feature for the accessory, `activate()` returns without an error and the session stays registered, with no timeout. Check the feature’s enrollment status (for example, with `AccessoryWorker/authorizationStatus(for:)`) before opening a session, rather than relying on an error.

## Topics

### Declaring features

[`protocol AccessoryFeature`](/documentation/AccessoryTransportExtension/AccessoryFeature)

A protocol that identifies a kind of work that the framework carries between your accessory and your app.

[`protocol AccessoryDataProvider`](/documentation/AccessoryTransportExtension/AccessoryDataProvider)

A protocol for an extension that provides your accessory’s data for one or more of the framework’s features.

### Managing feature sessions

[`protocol AccessoryFeatureSession`](/documentation/AccessoryTransportExtension/AccessoryFeatureSession)

A protocol that represents the session’s data provider.

[`protocol AccessoryFeatureSessionHandler`](/documentation/AccessoryTransportExtension/AccessoryFeatureSessionHandler)

A protocol that receives events from a data provider extension’s feature session.

[`protocol AccessoryFeatureRuntimeSession`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSession)

A protocol that represents a feature session’s transport extension.

[`protocol AccessoryFeatureRuntimeSessionHandler`](/documentation/AccessoryTransportExtension/AccessoryFeatureRuntimeSessionHandler)

A protocol that receives events from a transport extension’s feature session.

### Checking feature authorization

[`enum AccessoryFeatureAuthorizationStatus`](/documentation/AccessoryTransportExtension/AccessoryFeatureAuthorizationStatus)

A status that describes whether the system authorizes a feature for an accessory.

### Supporting background work

[`struct AccessoryWorker`](/documentation/AccessoryTransportExtension/AccessoryWorker)

A feature that carries data between your data provider and transport extensions.

[`struct AccessoryGPUWorker`](/documentation/AccessoryTransportExtension/AccessoryGPUWorker)

A feature for GPU work that carries data between your data provider and transport extensions.



---

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)