之前没接触过蓝牙开发,最近一直在跟蓝牙打交道。iOS开发蓝牙APP主要使用的是苹果原生的框架CoreBluetooth,这篇文章是对CoreBluetooth框架做一个简单的介绍,也是对前面一阶段的工作做一个梳理,加强自己对蓝牙开发这一块的理解。
概念
CBPeripheral
蓝牙外设,与APP通信的蓝牙设备,比如蓝牙手环。CBCentralManager
蓝牙管理中心,管理APP与外设之间的交互。CBService
蓝牙外设的服务,每一个外设都有0个或者多个服务。而每一个服务又可能包含0个或者多个蓝牙服务,也可能包含0个或者多个蓝牙特征。CBCharacteristic
特征,每一个蓝牙特征中都包含有一些数据或者信息。
代码分析
步骤
- 创建CBCentralManager。
- 在蓝牙开启的状态下扫描可连接的蓝牙外设。
- 根据连接目标蓝牙外设。
- 查询目标蓝牙外设下的服务。
- 遍历服务中的特征,获取特征中的数据或者保存某些可写的特征,或者设置某些特征值改变时,通知主动获取。
- 在通知更新特征中值的方法中读取特征中的数据(再设置特征的通知为YES的情况下)
- 读取特征中的值。
- 根据可写特征的UUID,向蓝牙外设写入数据。
创建CBCentralManager
创建完之后,就会调用一次CBCentralManagerDelegate代理方法
扫描到可用的外设之后,会调用CBCentralManagerDelegate
的此代理方法:
连接外设成功后,查找其具有的服务:
向外设写入数据:
与蓝牙外设断开连接:
中心设备连接中断回调
注意问题
1.在ios中蓝牙广播信息中通常会包含以下4种类型的信息。ios的蓝牙通信协议中不接受其他类型的广播信息。因为iOS端的限制,所以需要将设备的Mac地址放到kCBAdvDataManufacturerData这个字段中。
2.iOS10以上需要在info.plist里声明向用户申请蓝牙权限
3.扫描设备过程中,会弹出是否配对的弹窗(蓝牙固件传回来系统才会弹出的,手机端控制不了)。用户点击取消的时候,设备会进入假连接状态(杀掉APP之后,设备即断开连接).点击配对之后,系统就会把设备信息存在我的设备里,后续调retrive函数直接可以连接,相当于自动重连(杀掉APP之后,设备仍然连接中),如果需要断开连接的话,需要提醒用户去设置-蓝牙-忽略设备。暂未发现可以解决此问题的方法。
为何要获取蓝牙外设的Mac地址?
蓝牙外设的Mac地址,简而言之就是这个物理地址,每个设备都是唯一的,可以理解为身份证号。
一般在做BLE的开发中,会遇到通过APP去绑定一个蓝牙外设的需求,由于在APP关闭后,BLE就会断开连接,所以第二次打开APP的时候,就需要通过绑定时保存在本地或者数据库中的这个外设的信息,来进行定向扫描以及绑定。所以这里就涉及到了这个外设信息的唯一性的问题,如果不能保证保存的这个外设信息的唯一性的话,可能我第二次打开APP就连接不到之前的设备,或者连接到别的设备。
然而万恶的苹果在原生的CoreBluetooth中,将设备的Mac进行了封装(通过外设的Mac地址和手机的Mac地址进行了加密计算),最后对外提供了一个UUID,在一台手机上,一般情况,UUID就可以作为这个外设的唯一标识了,但是如果换了一台手机的话,可能就会发生变化,所以如果需求是需要在多台手机上的话,UUID可能就不太实用了。
特别是需要兼容安卓的情况下,安卓是可以获取到Mac地址的,所以我们就只能想办法获取外设的Mac地址了(正常情况下,为了方便iOS端,硬件工程师会把蓝牙地址放到外设的广播数据中(kCBAdvDataManufacturerData)字段)。