Contents

AccessoryTransportAppExtension

A protocol for an extension that transmits data to an accessory you develop.

Declaration

protocol AccessoryTransportAppExtension : AppExtension

Mentioned in

Overview

Implement this protocol in an extension with an EXExtensionPointIdentifier value of com.apple.accessory-transport-extension to relay data to your accessory. The extension supports sharing Wi-Fi networks and forwarding iOS system notifications.

Wi-Fi network sharing

Use this extension with Wi-Fi Infrastructure to share a Wi-Fi network with your accessory. The system calls your extension’s accept(sessionRequest:) method when it needs to establish a transport session for Wi-Fi sharing.

In your extension’s target properties, specify the extension point identifier:

<plist>
    <dict>
        <key>EXAppExtensionAttributes</key>
        <dict>
            <key>EXExtensionPointIdentifier</key>
            <string>com.apple.accessory-transport-extension</string>
        </dict>
    </dict>
</plist>

In your extension’s Swift code, implement the protocol and provide an event handler:

@main
struct TransportExtension: AccessoryTransportAppExtension {
    func accept(sessionRequest: AccessoryTransportSession.Request) -> AccessoryTransportSession.Request.Decision {
        return sessionRequest.accept {
            MyTransportEventHandler(session: sessionRequest.session)
        }
    }
}

class MyTransportEventHandler: AccessoryTransportSession.EventHandler {
    func invalidationHandler(error: AccessoryTransportSession.Error?) {
        // Clean up when the session ends.
    }
}

After accepting a session, your extension connects directly to the accessory using ASAccessorySession and delivers Wi-Fi network data using WINetworkSharingProvider.

Notification forwarding

For notification forwarding, set up your extension the same way as for Wi-Fi network sharing. The system invokes your extension to relay encrypted notification data from your app’s AccessoryDataProvider extension to your accessory.

Implement dataEventHandler(event:) in your event handler to receive and transmit data:

class MyTransportEventHandler: AccessoryTransportSession.EventHandler {
    func dataEventHandler(event: AccessoryTransportSession.DataEvent) {
        switch event {
        case .ciphertext(let data, let featureID):
            // Transmit encrypted notification data to accessory over Bluetooth.
            sendToAccessory(data)
        case .plaintext(let data, let featureID):
            // Transmit plaintext data to accessory.
            sendToAccessory(data)
        }
    }
    
    func invalidationHandler(error: AccessoryTransportSession.Error?) {
        // Clean up when the session ends.
    }
}

The system encrypts data using keys through your app’s AccessoryTransportSecurity (ATS) extension and then delivers the encrypted data as ciphertext to your handler. Your extension transmits the encrypted data to the accessory, which decrypts the data using shared encryption keys.

Support Bluetooth in the background

The system suspends your transport extension when it’s idle, and relaunches or resumes the extension when your accessory sends an update for a characteristic to which your extension subscribes (for more information on characteristics, see Transferring Data Between Bluetooth Low Energy Devices). If the system calls your central manager delegate’s centralManager(_:willRestoreState:) method so your extension can reconstitute its prior session state, the system initiates a cold relaunch. If your extension’s objects remain in memory and the system doesn’t call the method, the restart of the accessory is a warm resume, because your existing state persists unchanged. In either case, to restore a prior Bluetooth session, configure your extension’s target properties and use the Core Bluetooth framework’s CBCentralManager, as shown below.

In your extension’s target properties in Xcode, include the AccessorySetupKit entries your companion app declares for accessory permissions, so the extension has access to the same approved accessories. Add the bluetooth-central background mode to your extension’s target properties:

<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
</array>

When your extension instantiates CBCentralManager, use the transportStateRestoreIdentifier, which is unique to your transport extension instance. The system allocates background operation time and state restoration to one CBCentralManager per restoration identifier, and the system doesn’t grant background operation time or state restoration to additional instances.

Topics

Accepting session requests

Handling session events

Managing sessions

See Also

Wi-Fi network sharing