当前位置: 首页 > 工具软件 > CoreBlueTooth > 使用案例 >

iOS coreBluetooth编程中需要注意的问题

景岳
2023-12-01

一、iOS 设备作为中心设备(central device)时需要注意:

(1)一定要对central Manager保持强引用,也就是说central Manager需要是一个全局变量不能是局部变量,否则不能启动扫描。
(2)连接到peripheral之后,一定记得为peripheral设置代理,否则无法进行服务和特征的发现。
(3)有关CBCentralManagerDelegate协议
协议方法的意义都不难理解,但需要注意的是,蓝牙从开启、发现设备、连接设备、发现服务、发现特征到读写特征值、订阅特征着这六个步骤之间是有前后依赖关系的,每个步骤的执行都依赖前一个步骤的成功执行。
CBCentralManagerDelegate协议为以上6个步骤都定义了对应的回调方法,并且在回调方法中可以获取到当前步骤的执行结果。那么,就可以通过这个结果来决定是否继续进行下一个步骤。
比如每次调用CBCentralManager的初始化方法,都会回调代理方法-(void)centralManagerDidUpdateState:(CBCentralManager *)central。这个代理方法的调用意味着CBCentralManager对象初始化完毕,并且已经获取到当前设备的蓝牙功能状态,在这个回调方法中访问central.state就可以知道设备是否支持(已开启)蓝牙功能。只有当设备已开启蓝牙功能才能继续下一步——发现远端设备。
这种机制应该贯穿与整个蓝牙连接过程。
(4)确定远端设备是否支持某种功能
应该在对特征值进行读写或订阅操作之前,需要先知道这个特征是否支持和允许这些操作。判断特征支持和允许的操作可以通过特征的属性。特征的属性是个枚举值,可选的值有CBCharacteristicPropertyRead表示可读,CBCharacteristicPropertyNotify表示可订阅等等,具体可以参照接口文档。可以通过对特征的属性进行与操作来判定它是否支持某个选项。
例如:
if(CBCharacteristicPropertyNotify&certainCharacteristic.properties==CBCharacteristicPropertyNotify){
//可以订阅。。。。
}
(5)注意,BLE 4.0中规定,不会在设备之间建立长连接,而是启动了定时器,每隔一段时间,进行一次连接,连接持续时间只是一瞬间。因此,在BLE4.0中,发起连接的意义不是建立一条连接,而是开启这种定时连接的过程。发起连接的动作是由中心设备完成的,当调用了central的connectToPeripheral:方法后,这个定时连接的过程就开始了。中心设备每隔一段时间(在iPhone 5c上测试是一秒多)与目标远端设备连接一次,每次只是一瞬间,中心设备的所有读写操作都排着队,需要等待这一瞬间的到来才能够处理。如果队列中等待的读写操作过多,在这一次的连接时间中未能全部处理,就要等待下一次连接的瞬间到来,才能继续处理。
(6)每一次连接瞬间的发生,都会触发didConnectPeripheral:代理方法。如果在这个方法中不加判断地启动服务的发现,进而在发现服务的回调方法中又不加判断地启动特征的发现,那么这个从连接到发现特征的整个流程会定时从头到尾走一遍。如果实际上没有这个必要,最好对写在didConnectPeripheral:中的动作加一些判断,免得有太多无用的代码在执行。
(7)关于订阅功能,订阅某个特征值的更新,收到的特征值有可能和之前相同也可能不同,在使用特征值之前需要进行必要的判断。
(8)在需要发现设备的时候才需要扫描,其他动作比如发现服务、发现特征等由peripheral发出的动作都不依赖于扫描。理论上只要发现了设备就可以调用stopScan停止扫描了。在实际运用中,有时需要保证找到指定的特征,此时可以在找到了指定的特征后再停止扫描,否则继续扫描。当然也可以一发现设备就stopScan,如果发现特征不符的时候再重写开启扫描也可以。尽快停止扫描有利于省电。
(9)个人比较推荐在发现服务和发现特征的回调方法中,可以将发现到的所需的服务和特征保存下来,以便之后操作。
(10)如果对特征值进行的订阅,在不需要的时候最好尽快取消订阅,这样为远端设备省点。在完成蓝牙传输以后,尽快调用cancelPeripheralConnection:方法取消与目标远端设备的连接,为中心设备的省电。

二、iOS设备作为远端设备(peripheral device)时需要注意:

(1)在某个特征值接受订阅以后,如果要持续更新这个特征值,可以借助定时器。
(2)对于中心设备为iPhone的情况下,一个特征值,即NSData对象的长度不可以超过一定长度(用iPhone 5c作为中心设备测过它只能接收155字节;发送超过155字节的内容,不会报错,但中心设备只能接收到155字节)。
(3)在需要用一个特征值发送超过155字节的内容时需要对内容进行分割后发送。如果文件比较大,需要拆成比较多次发送,为了保证发送速度,推荐通过订阅来实现。特征值接受订阅以后,可以主动更新特征值,也就是可以主动发送分拆的内容,不用受到中心设备的连接间隔时间的限制。
(4)当调用的updateValue:ForCharacteristic:OnSubscribedCentrals:方法对被订阅的特征值进行更新,如果此时蓝牙的缓存满了,或者处理更新的队列满了,那么这次更新请求就会被丢弃。因此这个方法本身是有返回值的,成功发送了更新的特征值返回YES,被丢弃则返回NO。当遇到(3)中所述的要求内容完整性的情况,就需要用这个返回值判断需不需要进行重发。
(5) CBCharacteristic不支持mutableCopy。
(6)注意,不要往同一个peripheral manager中重复添加同一个服务,否则会出错。曾因为往peripheral manager中重复添加了一个服务,导致中心设备无法收到peripheral发出的订阅特征值的更新。也就是,调用了updateValue:ForCharacteristic:ToCentrals:方法,并且方法返回YES,也就是成功发送了。但是中心设备就是接收不到,还没有任何错误提示。。。。

 类似资料: