什么是Beacon
简单的理解,就是一个发送广播的BLE设备,在手机无需和设备进行连接的情况下发送数据,常应用于室内定位(车库,商场),智能打卡,提醒等场景。由于广播中可以传播少量的数据,部分体温计、温湿度计等只需传播少量信息的设备也经常使用这种模式。Apple的iBeacon,Google的Eddystone,Radius Network的AltBeacon,这些都是Beacon的一种实现形式。
iOS中操作iBeancon和Beacon
- iBeacon
iOS系统中可以使用CoreLocation,来方便的与iBeacon设备进行交互。 - 其他Beacon
设备厂使用自定义的协议,将数据写入广播AdvData中。对于这种Beacon设备的信息读取,不能使用CoreLocation,需要使用CoreBluetooth。
如何获取自定义Beacon的广播数据
关于操作iBeacon的Api,已经有大量的文章介绍,请各位自行搜索阅读。这里主要说一下其他Beacon设备的数据读取。与普通BLE设备一样,首先使用scanForPeripheralsWithServices:options:
方法扫描设备,之后在centralManager:didDiscoverPeripheral:advertisementData:RSSI:
回调方法的第三个参数advertisementData
中保存的就是设备广播的数据,这里会包括设备名称、设备电量、可连接状态、厂商自定义数据等内容。一般来说厂商会把一些额外的数据放到自定义数据里面,如温度、湿度、设备Mac地址等。我们拿到这个原始数据之后,按照相关协议去解析就可以得到我们想要的数据去做其他业务逻辑了。
如何获取AdvData的原始数据
advertisementData
保存的数据是系统已经处理过解析好的,iOS系统中想获取整个广播包的RawData是做不到的。其中CBAdvertisementDataManufacturerDataKey
字段中的数据由厂商自定义,系统不做解析,所以我们可以得到这个字段的原始数据。
厂商说数据写到AdvData中了,我怎么看不到
iOS系统中无法获取到原始报文的完整内容,只有在厂商自定义结构中的这部分数据才行。如果advertisementData
中没有你想要的数据,请让设备方工程师修改广播报内容,把数据放在厂商自定义结构中,这样你就可以在CBAdvertisementDataManufacturerDataKey
中看到了。如果对方反驳说“安卓可以得到啊”、“用蓝牙抓包工具能够抓到”诸如此类的话,请阅读以下内容,充分理解后把锅甩回去。
上图中红圈中的内容就是完整的AdvData,AdvData由N个AD Structure组层成,每个AD Structure的格式都是Length |AD Type|AD Data组成。图中第一个第一个字节02表示第一个AD Structure的长度是2个字节,即第一个AD Structure是由02加上紧跟着02后面的2个字节组成,因此,第一个AD Structure是:020106。以此类推,整个AdvData就可以分解成下面两个Structure
020106
1BFF570100A2E20A75A1671A187c7967856E24977C02EA055D085078
其中第二个Structure的Type,0xFF代表的就是厂商自定义内容,对应到iOS系统的advertisementData
中我们可以得到570100A2E20A75A1671A187c7967856E24977C02EA055D085078
而0201061BFF
我们是读不到的。如果你的设备厂商把数据写到了非0xFF类型的Structure中,那么在iOS系统中你就不能获取到这些数据了。
以上内容是一名iOSer在研究了2天Beacon之后进行的总结,其中部分概念的解读均为个人理解,如有错误之处,欢迎指正👏