2026 System Services
WWDC26 · 8 min · System Services
Find your accessory with Bluetooth Channel Sounding
Get started with Channel Sounding to bring distance and direction awareness to your Bluetooth accessories. Dive into the new Nearby Interaction and Core Bluetooth APIs, and walk through the accessory-side changes you’ll need. Optimize power consumption while ensuring a smooth, responsive experience.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 4 snippets
Start a Core Bluetooth Channel Sounding session
import CoreBluetooth
func isChannelSoundingSupported() -> BOOL {
guard centralManager.state == .poweredOn else { return }
if #available(iOS 27.0, *) {
// Check current device supports Bluetooth Channel Sounding
return CBCentralManager.supportsFeatures(.channelSounding)
}
}
func startChannelSounding(_ peripheral: CBPeripheral) {
guard peripheral.isConnected else { return }
if #available(iOS 27.0, *) {
// Step 1: Create a CBChannelSoundingSessionConfiguration
let config = CBChannelSoundingSessionConfiguration(role: .initiator)
// Step 2: Start the channel sounding session
peripheral.startChannelSoundingSession(config)
}
} Receive distance results and cancel a session
import CoreBluetooth
// Receive distance results
func peripheral(_ peripheral: CBPeripheral,
didReceive results: CBChannelSoundingProcedureResults?,
error: Error?) {
guard let results = results else { return }
let distance = results.distance
// Do something with distance
}
// Cancel a Channel Sounding session
func cancelChannelSounding(_ peripheral: CBPeripheral) {
guard peripheral.isConnected else { return }
if #available(iOS 27.0, *) {
// Cancel the channel sounding session
peripheral.cancelChannelSoundingSession(config)
}
}
func peripheral(_ peripheral: CBPeripheral,
didCompleteChannelSoundingSession error: Error?) {
// Session is complete
} Start a Nearby Interaction Channel Sounding session
import CoreBluetooth
import NearbyInteraction
// Configure a Nearby Interaction Channel Sounding session
func startChannelSoundingThroughNearbyInteraction(_ peripheral: CBPeripheral) {
if #available(iOS 27.0, *) {
// Step 1: Check current device supports Bluetooth Channel Sounding
guard NISession.deviceCapabilities.supportsBluetoothChannelSounding else { return }
// Step 2: Create an NINearbyAccessoryConfiguration
let config = NINearbyAccessoryConfiguration(
bluetoothChannelSoundingIdentifier: peripheral.identifier,
previousChannelSoundingIdentifier: nil)
// Step 3: Enable camera assistance for direction support
if NISession.deviceCapabilities.supportsCameraAssistance {
config.isCameraAssistanceEnabled = true
}
}
} Run a Nearby Interaction Channel Sounding session
import CoreBluetooth
import NearbyInteraction
// Run a Nearby Interaction Channel Sounding session
func runChannelSoundingThroughNearbyInteraction(_ config: NINearbyAccessoryConfiguration) {
// Create an NISession
let session = NISession()
session.delegate = self
// Run the NISession with the accessory configuration
session.run(config)
}
// Improve Nearby Interaction direction outputs
func updateAccessoryMotionState(_ isMoving: Bool) {
NIMotionActivityState motionState = isMoving ? .moving : .stationary
// Tell NISession about.the accessory's motion state
session.updateMotionState(motionState, forObjectWithToken: object.discoveryToken)
}
// Receive NISession updates
func session(_ session: NISession, didUpdate nearbyObjects: [NINearbyObjects]) {
guard let object = nearbyObjects.first else { return }
if let distance = object.distance {
// Do something with distance
}
if let direction = object.horizontalAngle {
// Do something with horizontal angle
}
} Resources
Related sessions
-
15 min -
23 min