不同设备连接同一个蓝牙设备,获取到的它的唯一标志是不一样的CBUUID
蓝牙重连后,特征值对象会改变,原来的特征值对象就不生效了,需要重新保存
蓝牙的命令发送和数据接收应该遵循发送后处理接收,接收后再次发送的原则,否则容易出现请求之后返回结果错误的问题
通知提醒功能:
手机只设置开关,实现iOS的消息通知,手表等移动穿戴设备需要自行通过ANCS技术来实现(手机广播了一个特征值,通过这个特征值往外发送消息通知)
链接蓝牙操作流程:
1.开启蓝牙开关
2.搜索设备,通过回调找到要链接的设备(已链接过设备需要通过设备的UUID获取)
CBPeripheral *peripheral = [self.centerManager retrievePeripheralsWithIdentifiers:@[[[NSUUID alloc] initWithUUIDString:peripheralUUID]]].firstObject;
3.连接设备,链接设备成功后,设置CBPeripheral的代理(接收读写状态消息等),发现服务
// 设置设备代理 [peripheral setDelegate:self]; [peripheral discoverServices:self.supportServiceUUIDs];
4.发现服务后,发现服务下面的特征值
for (CBService *service in peripheral.services) { [peripheral discoverCharacteristics:nil forService:service]; }
4.发现特征值后,通过蓝牙硬件开发商给到的UUID获取保存需要的读/写/广播特征值,同时开启对特征值数据的读写监听,需要获取通知数据的,还要开启通知(所有特征值发现完之后,应该执行蓝牙设备要求的授权绑定等指令操作)
for (CBCharacteristic *characteristic in service.characteristics) { if ([config.readUUDs containsObject:characteristic.UUID.UUIDString]) { [peripheral readValueForCharacteristic:characteristic]; [read addObject:characteristic]; } if ([config.writeUUIDs containsObject:characteristic.UUID.UUIDString]) { [peripheral readValueForCharacteristic:characteristic]; [write addObject:characteristic]; } }
[mgr.peripheral setNotifyValue:YES forCharacteristic:characteristic];
5.所有获取到数据的代理函数如下
#pragma mark -- 接收到数据回调 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
6.写数据结束后状态回调
#pragma mark -- 写入数据回调 - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
写入数据可能失败,可能没有回调,所以不能一直等待回调之后继续下一步写入,应设置超时默认已完成或已失败
7.每次读取到的数据可能来自不同的特征值,需要根据设备特性,灵活的组合结果数据(如同步操作时,可能是1.发起请求,2.A返回同步操作反馈,3.接着B返回同步数据,4.一天数据同步完成结束后又需要手机反馈同步状态给蓝牙设备,接着蓝牙设备吐出数据或反馈同步已完成)
8.如果出现了断连需要重连时,蓝牙外设/服务/特征值均不需要重新赋值(压根没变),但是需要重新开启一段 连接设备->发现服务->发现特征值监听特征值数据的过程(3.4),全部完成之后,即可以开心的发接数据了,如果缺少一环,则是会无法接受到数据反馈