iOS蓝牙开发:如何获知配对完成状态?
如何监听蓝牙配对/绑定完成的时机
当然有对应的回调可以用!在iOS的CoreBluetooth框架里,你可以通过两个核心代理的回调组合来准确判断配对完成的时机,下面给你详细拆解:
1. 核心连接状态回调:CBCentralManagerDelegate
当你发起连接后,系统弹出配对弹窗,用户完成配对(或取消)后,centralManager(_:didUpdateConnectionState:for:)会被触发:
- 如果配对成功且连接稳定,外设的
state会变为.connected,这是最直接的配对完成信号 - 如果用户取消配对,外设状态会变为
.disconnected,或者停留在.connecting(取决于设备逻辑)
示例代码:
func centralManager(_ central: CBCentralManager, didUpdateConnectionState peripheral: CBPeripheral, error: Error?) { switch peripheral.state { case .connected: print("✅ 配对完成,设备已稳定连接!") // 这里可以开始初始化服务发现,准备发送指令 peripheral.delegate = self peripheral.discoverServices(nil) case .disconnected: print("❌ 连接断开,可能配对失败或用户取消") case .connecting: print("🔄 正在连接/配对中,请等待系统弹窗操作") default: break } }
2. 结合服务/特征访问回调确保可靠性
有些设备配对完成后,加密密钥需要短暂同步时间,此时即使连接状态是.connected,直接访问加密的服务/特征可能会失败。这时候可以通过CBPeripheralDelegate的回调来确认:
- 当你调用
discoverServices(_:)后,peripheral(_:didDiscoverServices:)触发,说明设备已准备好接收指令 - 如果你要写入的特征需要加密,
peripheral(_:didWriteValueFor:error:)会返回结果:没有错误就说明配对+加密都完成了
示例代码:
// 发现服务后,继续发现特征 func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { guard let services = peripheral.services, error == nil else { print("发现服务失败: \(error?.localizedDescription ?? "未知错误")") return } for service in services { peripheral.discoverCharacteristics(nil, for: service) } } // 发现目标特征后,发送指令 func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let characteristics = service.characteristics, error == nil else { print("发现特征失败: \(error?.localizedDescription ?? "未知错误")") return } // 替换成你的指令特征UUID guard let commandChar = characteristics.first(where: { $0.uuid == UUID(uuidString: "你的特征UUID") }) else { print("未找到目标指令特征") return } // 构造指令数据并发送 let commandData = "你的指令内容".data(using: .utf8)! peripheral.writeValue(commandData, for: commandChar, type: .withResponse) } // 确认指令发送结果 func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { if let error = error { print("指令发送失败: \(error.localizedDescription)") // 如果是加密不足错误,说明配对可能未完成,可尝试重新连接 if (error as NSError).code == CBATTError.insufficientEncryption.rawValue { print("⚠️ 加密不足,配对可能未完成,请检查") } } else { print("🎉 指令发送成功!") } }
额外提示
- 如果你的设备需要长期绑定(下次连接不弹窗),配对完成后系统会自动保存配对信息,后续连接时
centralManager(_:didUpdateConnectionState:for:)会直接进入.connected状态,无需再处理配对弹窗 - 不要在配对弹窗显示期间主动发起服务发现或特征访问,必须等待连接状态更新后再操作,否则会返回加密错误
内容的提问来源于stack exchange,提问作者Yogurt
相关产品推荐
相关产品推荐

