You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:30:01