iOS无法通过Service UUID连接蓝牙设备并读写特征(Android正常)
iOS蓝牙连接问题排查方案
问题概述
iOS平台无法通过Service UUID 0000FD00-0000-1000-8000-00805F9B34FB 连接蓝牙设备,也无法读写特征 0000FD03-0000-1000-8000-00805F9B34FB,但同一设备在Android平台可正常连接传输。当前代码既无法检测到设备,也无报错信息。
相关UUID信息
- Service UUID:
0000FD00-0000-1000-8000-00805F9B34FB - Read特征UUID:
0000FD03-0000-1000-8000-00805F9B34FB
当前使用代码
class BluetoothManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate { var centralManager: CBCentralManager! var peripheralDevice: CBPeripheral? var eSIMCharacteristic: CBCharacteristic? // UUIDs for the custom service and characteristic let eSIMServiceUUID = CBUUID(string: "0000FD00-0000-1000-8000-00805F9B34FB") override init() { super.init() // Initialize the CBCentralManager centralManager = CBCentralManager(delegate: self, queue: nil) } // Central Manager state change (check if Bluetooth is available) func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == .poweredOn { // Start scanning for the charging box centralManager.scanForPeripherals(withServices: [eSIMServiceUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: true]) } } // Discovered a peripheral (charging box) func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { print("peripheral", peripheral, peripheral.identifier) // Stop scanning and connect to the peripheral centralManager.stopScan() peripheralDevice = peripheral peripheralDevice?.delegate = self centralManager.connect(peripheral, options: nil) } // Connected to the peripheral (charging box) func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { // Discover services on the peripheral print("Connected to device: \(peripheral.name ?? "Unknown")") peripheral.discoverServices([eSIMServiceUUID]) } // Discovered services on the peripheral func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { print("error occured", error) } }
排查与修复步骤
先扫描所有设备,验证设备是否可被iOS发现
iOS的scanForPeripherals(withServices:)仅会发现主动广播了对应Service UUID的设备,而Android允许扫描所有设备后再筛选。修改扫描代码,传nil给withServices:centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])如果能发现目标设备,说明设备没有广播
FD00这个Service UUID,此时需要修改扫描逻辑:先扫所有设备,通过名称或identifier匹配后再连接,连接后再发现服务。补全关键代理方法,获取错误信息
当前代码缺少多个核心回调,无法定位连接、扫描失败的原因,添加以下方法:// 连接失败回调 func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { print("Failed to connect: \(error?.localizedDescription ?? "Unknown error")") } // 断开连接回调 func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { print("Disconnected: \(error?.localizedDescription ?? "No error")") } // 服务发现后,遍历服务并发现特征 func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { if let error = error { print("Discover services error: \(error)") return } guard let services = peripheral.services else { return } for service in services { if service.uuid == eSIMServiceUUID { peripheral.discoverCharacteristics(nil, for: service) } } } // 特征发现回调 func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if let error = error { print("Discover characteristics error: \(error)") return } guard let characteristics = service.characteristics else { return } for characteristic in characteristics { if characteristic.uuid == CBUUID(string: "0000FD03-0000-1000-8000-00805F9B34FB") { eSIMCharacteristic = characteristic // 读取特征值 peripheral.readValue(for: characteristic) } } } // 特征值读取回调 func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let error = error { print("Read value error: \(error)") return } if let data = characteristic.value { print("Received data: \(data)") } }检查蓝牙权限配置
在Info.plist中添加蓝牙权限描述:- iOS 13及以上:添加
NSBluetoothAlwaysUsageDescription(字符串类型,描述蓝牙使用场景) - iOS 12及以下:添加
NSBluetoothPeripheralUsageDescription
缺少权限会导致扫描静默失败,无任何回调。
- iOS 13及以上:添加
验证设备端UUID一致性
确认设备端广播的Service UUID和代码中使用的完全一致,虽然CBUUID不区分大小写,但部分设备可能存在UUID格式差异(比如省略分隔符等),需和硬件端确认。
内容的提问来源于stack exchange,提问作者Mallikarjun C




