通过 Bluetooth Channel Sounding 查找你的配件
Find your accessory with Bluetooth Channel Sounding
2026年6月10日
一句话判断
这场 Session 最值得关注的一件事是:Bluetooth Channel Sounding (蓝牙信道探测) 终于让纯蓝牙配件摆脱了 RSSI (接收信号强度指示) 测距的“玄学”,但“仅限前台”的限制说明苹果在功耗和射频干扰上还没完全搞定,目前它更适合“主动寻找”而非“无感追踪”。
这场 Session 讲了什么
以前做蓝牙配件测距,大家只能捏着鼻子用 RSSI。这玩意儿受环境干扰极大,隔着承重墙和面对面可能信号一样强,用户吐槽“找不到”是家常便饭。想精准就得加 UWB (超宽带) 芯片,但成本和功耗直接劝退一堆中小硬件厂。
现在 Bluetooth 6.3 带来了 Channel Sounding (信道探测)。原理不复杂:iPhone 在不同信道发信号,配件反射回来,系统通过计算相位差来测算物理距离。苹果给开发者准备了两条路:只测距离用 Core Bluetooth,要距离加方向用 Nearby Interaction (附近交互)。这对做智能家居、防丢器、IoT 配件的团队是个大新闻,意味着不用改硬件 BOM 表加 UWB,也能拿到相对靠谱的测距数据。
值得深挖的点
Core Bluetooth 与 Nearby Interaction 的取舍博弈
苹果把测距拆成两套 API 绝非多此一举。Core Bluetooth 的 startChannelSoundingSession 只返回距离,调用简单,不需要额外权限。而 Nearby Interaction 不仅能返回距离,还能结合 CameraAssistance (相机辅助) 给出精确方向。
这里的 trade-off 很明显:方向感知需要调用相机和 N1 芯片的算力,这意味着你需要向用户索要相机权限。一旦用户拒绝,你的“箭头指引”功能就直接瘫痪。更有趣的是,Nearby Interaction 允许你通过 updateMotionState 告诉系统配件是 .moving (移动中) 还是 .stationary (静止)。这说明苹果在底层做了深度的传感器融合,把配件的运动状态纳入了滤波算法的权重计算中。如果你做的是一个固定在墙上的温控器,务必传入 .stationary,这能大幅减少方向指针的“漂移”现象。
“仅限前台”背后的功耗与射频妥协
Session 里轻描淡写地提了一句:在 iOS 27 中,Channel Sounding 只能在 App 处于前台时使用,切到后台会话就会暂停。这其实是个巨大的限制。防丢器最关键的痛点是“后台无感寻物”,现在只能前台用,直接砍掉了一半的使用场景。
为什么这么保守?因为 Channel Sounding 需要在 2.4GHz 频段频繁切换信道发送音调。这不仅极其耗电,还会和 Wi-Fi 以及其他蓝牙设备抢占空口资源。苹果明确提到,当其他蓝牙或 Wi-Fi 活动增加时,系统会自动降低测距频率。这说明目前的基带调度还无法在“高频测距”和“系统整体网络体验”之间做到完美平衡。在设计产品时,千万别把它当成 AirTag 的平替,把它当成一个“雷达扫描仪”——用户主动点开 App,看着距离数字变小,找到目标后退出,这才是目前最合理的交互范式。
代码片段
1. 启动 Core Bluetooth 测距并获取距离
场景:只需要知道配件离用户有多远,不需要方向指引,且不想申请相机权限。
import CoreBluetooth
func startSounding(peripheral: CBPeripheral) {
guard peripheral.state == .connected else { return }
if #available(iOS 27.0, *) {
// 检查当前设备是否支持蓝牙信道探测
guard CBCentralManager.supportsFeatures(.channelSounding) else { return }
// 创建配置,iPhone 作为发起方 (initiator)
let config = CBChannelSoundingSessionConfiguration(role: .initiator)
// 开始测距会话
peripheral.startChannelSoundingSession(config)
}
}
// 接收测距结果
func peripheral(_ peripheral: CBPeripheral,
didReceive results: CBChannelSoundingProcedureResults?,
error: Error?) {
guard let distance = results?.distance else { return }
// distance 是以米为单位的浮点数,系统已自动做过平滑处理
print("当前距离: \(distance) 米")
}
坑:distance 可能会返回 nil,当环境干扰过大导致测距失败时,系统会直接丢弃异常值,UI 层必须做好空状态的兼容。
2. 使用 Nearby Interaction 获取距离与方向
场景:需要像 AirTag 那样在屏幕上显示指向配件的箭头,且配件本身有运动状态变化。
import NearbyInteraction
import CoreBluetooth
func startDirectionalSounding(peripheral: CBPeripheral) {
if #available(iOS 27.0, *) {
// 检查设备是否支持蓝牙信道探测
guard NISession.deviceCapabilities.supportsBluetoothChannelSounding else { return }
// 使用 Core Bluetooth 的 peripheral.identifier 作为配置标识
let config = NINearbyAccessoryConfiguration(
bluetoothChannelSoundingIdentifier: peripheral.identifier
)
let session = NISession()
session.delegate = self
session.run(config)
// 告知系统配件的运动状态,优化方向估算算法
updateMotionState(session: session, token: config.discoveryToken, isMoving: false)
}
}
func updateMotionState(session: NISession, token: NIDiscoveryToken, isMoving: Bool) {
let state: NIMotionActivityState = isMoving ? .moving : .stationary
// 传入 discoveryToken 和运动状态
session.updateMotionState(state, for: token)
}
坑:使用 Nearby Interaction 必须确保配件已通过 AccessorySetupKit 完成配对,且如果方向输出依赖 CameraAssistance,必须在 Info.plist 中配置相机权限,否则只能拿到距离。
最佳实践
对于已有项目,如果你的配件还在用老旧的蓝牙 5.x 芯片,这套 API 对你毫无意义。赶紧催促硬件团队选型支持 Bluetooth 6.3 且包含 PCT (基于相位的测距) 功能的芯片,特别是必须支持 mode-0 和 mode-2,且 T_FCS (音调间隔时序) 至少达到 100µs。
新项目在交互设计上,请彻底放弃“后台自动弹窗提示距离”的幻想。把测距功能包装成“精准查找”模式,引导用户在前台主动触发。同时,务必实现优雅的降级策略:当检测到设备没有 N1 芯片,或者用户拒绝了相机权限时,自动从 Nearby Interaction 降级到 Core Bluetooth 仅显示距离数字,甚至最终降级回传统的 RSSI 信号强度条。
还有什么值得关注
- N1 芯片首秀:字幕中明确提到 Channel Sounding 需要搭载 N1 芯片的 iPhone,这暗示苹果可能用 N 系列重新命名了新一代的空间感知芯片。
- AccessorySetupKit 强绑定:无论是 Core Bluetooth 还是 Nearby Interaction,Session 都反复强调必须先通过 AccessorySetupKit 完成配对,苹果正在收拢外设配对的入口。
- 内置数据平滑:iOS 底层已经接管了测距数据的异常值过滤和平滑处理,开发者不需要再自己手写滤波算法来防止数字乱跳了。