What's New / Media, Audio & Capture

What's new in AudioAccessoryKit

+10 NewiOS

AudioAccessoryKit provides APIs for audio accessories such as headphones. It exposes accessory capabilities, sensor data, and device configuration, with sensor messages reporting head-tracking state.

The 27 SDK adds 10 APIs with no deprecations or removals. New types are the AccessorySensorUpdates struct and the AudioAccessoryError enum. New members include Capabilities.audioSpatialization, Capabilities.headTracking, AccessoryControlDevice.Configuration.init, and the Handler methods activate, invalidate, headTrackingStateDidChange, and didReceiveAccessorySensorMessage.

New

10
struct

AccessorySensorUpdates

NewiOS
public struct AccessorySensorUpdates : AsyncSequence, Sendable

Subscribes to a stream of raw sensor data packets from a connected accessory.

An Audio Rendering Extension launched by AudioToolbox uses this type to receive sensor data from a 3P accessory that has registered .headTracking via AccessoryControlDevice. Data is brokered through audioaccessoryd over XPC.

No XPC resources are acquired until iteration begins. Cancel the owning Task to stop receiving updates and release the connection.

## Usage

guard AccessorySensorUpdates.isSupported else { return }
let updates = AccessorySensorUpdates(for: accessoryIdentifier)
sensorTask = Task { [weak self] in
    do {
        for try await update in updates {
            switch update {
            case .packet(let data):
                self?.processSensorData(data)
            case .malformedPacket:
                // Non-terminal; stream continues with subsequent packets
                break
            }
        }
    } catch AccessorySensorUpdates.StreamError.connectionLost {
        // Terminal; stream is over
    }
}
Declaration
public struct AccessorySensorUpdates : AsyncSequence, Sendable {

    /// The type of element produced by this asynchronous sequence.
    public typealias Element = AccessorySensorUpdates.Update

    /// A single update emitted by the stream.
    public enum Update : Sendable, Hashable {

        /// A valid sensor data packet from the accessory.
        case packet(Data)

        /// A malformed packet was received; the connection remains open and
        /// subsequent packets may still be valid.
        case malformedPacket

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: AccessorySensorUpdates.Update, b: AccessorySensorUpdates.Update) -> Bool

        /// Hashes the essential components of this value by feeding them into the
        /// given hasher.
        ///
        /// Implement this method to conform to the `Hashable` protocol. The
        /// components used for hashing must be the same as the components compared
        /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
        /// with each of these components.
        ///
        /// - Important: In your implementation of `hash(into:)`,
        ///   don't call `finalize()` on the `hasher` instance provided,
        ///   or replace it with a different instance.
        ///   Doing so may become a compile-time error in the future.
        ///
        /// - Parameter hasher: The hasher to use when combining the components
        ///   of this instance.
        public func hash(into hasher: inout Hasher)

        /// The hash value.
        ///
        /// Hash values are not guaranteed to be equal across different executions of
        /// your program. Do not save hash values to use during a future execution.
        ///
        /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
        ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
        ///   The compiler provides an implementation for `hashValue` for you.
        public var hashValue: Int { get }
    }

    public enum StreamError : Error, LocalizedError, Sendable, Hashable {

        /// The XPC connection was permanently lost; the stream is finished.
        case connectionLost

        /// A localized message describing what error occurred.
        public var errorDescription: String? { get }

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: AccessorySensorUpdates.StreamError, b: AccessorySensorUpdates.StreamError) -> Bool

        /// Hashes the essential components of this value by feeding them into the
        /// given hasher.
        ///
        /// Implement this method to conform to the `Hashable` protocol. The
        /// components used for hashing must be the same as the components compared
        /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
        /// with each of these components.
        ///
        /// - Important: In your implementation of `hash(into:)`,

Truncated.

enum

AudioAccessoryError

NewiOS
public enum AudioAccessoryError : Error, LocalizedError, Sendable, Hashable
Declaration
public enum AudioAccessoryError : Error, LocalizedError, Sendable, Hashable {

    case invalidDataSize

    case notActivated

    /// Returns a Boolean value indicating whether two values are equal.
    ///
    /// Equality is the inverse of inequality. For any values `a` and `b`,
    /// `a == b` implies that `a != b` is `false`.
    ///
    /// - Parameters:
    ///   - lhs: A value to compare.
    ///   - rhs: Another value to compare.
    public static func == (a: AudioAccessoryError, b: AudioAccessoryError) -> Bool

    /// Hashes the essential components of this value by feeding them into the
    /// given hasher.
    ///
    /// Implement this method to conform to the `Hashable` protocol. The
    /// components used for hashing must be the same as the components compared
    /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
    /// with each of these components.
    ///
    /// - Important: In your implementation of `hash(into:)`,
    ///   don't call `finalize()` on the `hasher` instance provided,
    ///   or replace it with a different instance.
    ///   Doing so may become a compile-time error in the future.
    ///
    /// - Parameter hasher: The hasher to use when combining the components
    ///   of this instance.
    public func hash(into hasher: inout Hasher)

    /// The hash value.
    ///
    /// Hash values are not guaranteed to be equal across different executions of
    /// your program. Do not save hash values to use during a future execution.
    ///
    /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
    ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
    ///   The compiler provides an implementation for `hashValue` for you.
    public var hashValue: Int { get }
}
typealias

ID

NewiOS
public typealias ID = String

A type representing the stable identity of the entity associated with an instance.

init

AccessoryControlDevice.Configuration.init

NewiOS
public init(devicePlacement: AccessoryControlDevice.Placement? = nil, deviceCapabilities: AccessoryControlDevice.Capabilities, primaryAudioSourceDeviceIdentifier: Data? = nil, secondaryAudioSourceDeviceIdentifier: Data? = nil, spatialExtensionDescription: AudioComponentDescription?)

Creates a new device configuration with spatial audio support.

Parameters

devicePlacement
The current placement state (e.g., .offHead, .onHead, .inEar) - only applicable with .placement capability
deviceCapabilities
The capabilities supported by the device (e.g., [.placement, .audioSpatialization])
primaryAudioSourceDeviceIdentifier
Bluetooth address of the primary audio source (only applicable with .audioSwitching capability)
secondaryAudioSourceDeviceIdentifier
Bluetooth address of secondary audio source (only applicable with .audioSwitching capability)
spatialExtensionDescription
The audio component description for the spatial audio rendering extension (only applicable with .audioSpatialization capability)
let

Capabilities.audioSpatialization

NewiOS
public static let audioSpatialization: AccessoryControlDevice.Capabilities

Device supports audio spatialization

let

Capabilities.headTracking

NewiOS
public static let headTracking: AccessoryControlDevice.Capabilities

Device supports head tracking for audio spatialization

func

Handler.activate

NewiOS
func activate(for session: AudioAccessoryHeadTracking.Session)

Called when a notification session has been established.

Parameters

session
A type enabling communication back to the extension host.
func

Handler.didReceiveAccessorySensorMessage

NewiOS
func didReceiveAccessorySensorMessage(_ message: TransportMessage)
func

Handler.headTrackingStateDidChange

NewiOS
func headTrackingStateDidChange(isActive: Bool)
func

Handler.invalidate

NewiOS
func invalidate()

No APIs match your filter.

← More in Media, Audio & Capture