如何在macOS(Swift)中解析iBeacon并提取核心参数
解析iBeacon广播数据提取核心字段(Swift实现)
我之前做iBeacon相关业务时,天天跟这个代理方法打交道,太清楚怎么从广播数据里抠出major、minor、UUID这些核心字段了!咱们直接从centralManager(_:didDiscover:advertisementData:rssi:)这个方法入手,一步步拆解:
第一步:先判断是不是iBeacon广播数据
不是所有外设广播都是iBeacon,所以先做个校验:苹果的iBeacon会在广播数据里带kCBAdvDataAppleBeaconKey这个键,或者你也可以检查服务UUID是否包含iBeacon的专属UUID FEAA。
第二步:提取并解析原始广播数据
拿到iBeacon的原始Data后,按照iBeacon的固定格式来拆分字段:
iBeacon的广播数据格式是固定25字节:[2字节Beacon Type] + [16字节UUID] + [2字节Major] + [2字节Minor] + [1字节TxPower]
完整代码示例
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { // 1. 校验是否为iBeacon广播 guard let beaconData = advertisementData[kCBAdvDataAppleBeaconKey as String] as? Data else { // 不是iBeacon,直接返回 return } // 2. 校验数据长度是否符合iBeacon标准(必须是25字节) guard beaconData.count == 25 else { print("无效的iBeacon数据长度") return } var beaconBytes = [UInt8](beaconData) // 3. 提取各个字段 // Beacon Type(前2字节,固定为0x0215) let beaconType = UInt16(beaconBytes[0]) << 8 | UInt16(beaconBytes[1]) print("Beacon Type: \(String(format: "0x%04X", beaconType))") // UUID(接下来16字节) let uuidData = Data(beaconBytes[2..<18]) guard let uuid = UUID(data: uuidData) else { print("UUID解析失败") return } print("UUID: \(uuid.uuidString)") // Major(接下来2字节,大端序) let major = UInt16(beaconBytes[18]) << 8 | UInt16(beaconBytes[19]) print("Major: \(major)") // Minor(接下来2字节,大端序) let minor = UInt16(beaconBytes[20]) << 8 | UInt16(beaconBytes[21]) print("Minor: \(minor)") // TxPower(最后1字节,有符号整数) let txPower = Int8(bitPattern: beaconBytes[22]) print("TxPower: \(txPower) dBm") }
几个要注意的细节
- 字节序问题:Major和Minor字段是大端序(Big Endian)存储的,所以要把高字节左移8位再加低字节,不能直接按小端序解析
- TxPower是有符号的:它的取值范围一般是-127到127,所以要用
Int8来接收,不能用无符号的UInt8 - 数据长度校验:一定要检查beaconData的长度是否为25字节,避免越界访问或者解析出错误数据
内容的提问来源于stack exchange,提问作者Alexander Spirichev
相关产品推荐
相关产品推荐

