iOS 16.5下CBPeripheralManager如何在蓝牙广播中传递UInt8字节数组?
解决iOS蓝牙广告传递字节数组的问题
问题原因
CBAdvertisementDataLocalNameKey 字段是专门用于设置蓝牙设备本地名称的,仅接受 NSString 类型的值。直接传入 [UInt8] 字节数组时,系统会自动忽略这个无效值,不会抛出错误但也不会将数据放入广告包中。
正确实现方式
要传递自定义字节数组,得用蓝牙广告规范里专门承载二进制数据的字段,推荐两种方案:
方案1:使用制造商数据(CBAdvertisementDataManufacturerDataKey)
制造商数据用于传递和设备制造商相关的自定义数据,需要指定一个16位的制造商ID(如果没有官方分配的ID,可临时用测试ID如0xFFFE,生产环境要向蓝牙技术联盟申请合法ID)。
示例代码:
import CoreBluetooth class Advertiser: NSObject, CBPeripheralManagerDelegate { private var peripheralManager: CBPeripheralManager! override init() { super.init() peripheralManager = CBPeripheralManager(delegate: self, queue: nil) } func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { if peripheral.state == .poweredOn { // 准备要传递的字节数组 let customBytes: [UInt8] = [1, 2, 3] let manufacturerData = Data(customBytes) // 构建广告字典 let advertisementData: [String: Any] = [ CBAdvertisementDataManufacturerDataKey: manufacturerData, // 可选:同时设置设备本地名称 CBAdvertisementDataLocalNameKey: "MyDevice" ] // 开始广播 peripheralManager.startAdvertising(advertisementData) } } }
方案2:使用服务数据(CBAdvertisementDataServiceDataKey)
服务数据用于传递和特定蓝牙服务相关的自定义数据,需要定义一个自定义UUID(或使用已有的服务UUID)来标识数据所属的服务。
示例代码:
import CoreBluetooth class Advertiser: NSObject, CBPeripheralManagerDelegate { private var peripheralManager: CBPeripheralManager! // 自定义服务UUID(可自行生成唯一值) private let customServiceUUID = CBUUID(string: "YOUR_CUSTOM_UUID") override init() { super.init() peripheralManager = CBPeripheralManager(delegate: self, queue: nil) } func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { if peripheral.state == .poweredOn { // 准备要传递的字节数组 let customBytes: [UInt8] = [1, 2, 3] let serviceData = Data(customBytes) // 构建广告字典 let advertisementData: [String: Any] = [ CBAdvertisementDataServiceDataKey: [customServiceUUID: serviceData], // 可选:同时设置设备本地名称 CBAdvertisementDataLocalNameKey: "MyDevice" ] // 开始广播 peripheralManager.startAdvertising(advertisementData) } } }
注意事项
- 蓝牙广告包总大小有限制(通常约20字节),自定义数据不能过长,否则会被截断或无法正常广播。
- 测试时需要用另一台设备通过
CBCentralManager扫描,在扫描回调中解析advertisementData对应的字段(CBAdvertisementDataManufacturerDataKey或CBAdvertisementDataServiceDataKey)来获取字节数组。 - 生产环境使用制造商ID时,必须使用蓝牙技术联盟分配的合法ID,避免和其他设备冲突。
内容的提问来源于stack exchange,提问作者denver
相关产品推荐
相关产品推荐

