多设备其实和单设备并没有什么太大的变化。至少初级写的时候,只是代码量多了一些。但是后面各种状态还有代码的优化工作挺多。
@interface CentralManager ()<CBCentralManagerDelegate, CBPeripheralDelegate,CentralManagerDelegate> { /** 这里只做多设备简单介绍。如果设备很多,或者设备不固定,可以考虑使用数组等进行优化 */ CBPeripheral *_devicePeripheral; //硬件设备 (设备1) CBPeripheral *_wristbandPeripheral; //手环设备 (设备2)
CBCharacteristic *_deviceCharacteristic; //硬件设备服务特征 (用来发送指令)
CBCharacteristic *_wristbandCharacteristic; //手环设备服务特征 (发送指令,用来和手环进行数据交换,读取手环数据等)
//蓝牙管理类,这就是蓝牙Boss呀,没有他,你就别想做蓝牙
CBCentralManager *_manager;
}
这里添加了两个 CBPeripheral *成员变量。 每一个 CBPeripheral对应一个硬件设备,如果硬件过多,建议使用数组进行优化。 如果只是两个设备倒还不会有影响。另外建议使用swift,做起来会更快速一些。
#pragma mark - » 发现蓝牙设备
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
if (!peripheral.name) {
return;
}
//连接设备可以根据需求,写到两个方法里面,可以根据点击操作分别连接不同的设备。 我这里是直接进行了同时连接
//里面的字符串是硬件设备的名称。 也可以根据 广播等内容进行判断连接
//连接硬件设备
if ([peripheral.name rangeOfString:@"Device"].location != NSNotFound) {
[_manager connectPeripheral:peripheral options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:NO]}];
}
//连接手环设备
if ([peripheral.name rangeOfString:@"wristband"].location != NSNotFound) {
[_manager connectPeripheral:peripheral options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:NO]}];
}
}
#pragma mark - » 连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"连接成功:%@", peripheral.name);
if (_devicePeripheral == peripheral) {
_deviceBleState = BleManagerStateConnect;
_devicePeripheral = peripheral;
}else if (_wristbandPeripheral == peripheral) {
_wristbandBleState = BleManagerStateConnect;
_wristbandPeripheral = peripheral;
}
for (id listener in _listener) {
if ([listener respondsToSelector:@selector(didConnectDevicePeripheral:)]) {
[listener didConnectDevicePeripheral:peripheral];
}
}
/*
1、连接成功
2、发现服务
3、发现特征值
4、特征值 是用来 和蓝牙设备做交互使用的。如设置设备时间,或者读取设备数据。设置通知等
*/
//因为在后面我们要从外设蓝牙那边再获取一些信息,并与之通讯,这些过程会有一些事件可能要处理,所以要给这个外设设置代理
peripheral.delegate = self;
//找到该设备上的指定服务 调用完该方法后会调用代理CBPeripheralDelegate(现在开始调用另一个代理的方法了)
// [peripheral discoverServices:@[[CBUUID UUIDWithString:UUID_DEVICE_SERVER_0]]];
// [peripheral discoverServices:@[[CBUUID UUIDWithString:@"7480"]]];
[peripheral discoverServices:nil]; //发现服务
}
#pragma mark - » CBPeripheralDelegate #pragma mark - » 发现服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if (error == nil) {
NSLog(@"发现服务");
for (CBService *service in peripheral.services) {
NSLog(@"服务:%@", service);
//发现服务,然后去查找该服务的特征值 ,然后请转到下面的那个代理方法
[peripheral discoverCharacteristics:nil forService:service];
// if ([service.UUID isEqual:[CBUUID UUIDWithString:UUID_DEVICE_SERVER_0]]) {
// //查询服务所带的特征值
// // [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"FFE0"]] forService:service];
// [peripheral discoverCharacteristics:nil forService:service];
// }
}
}
}
#pragma mark - » 发现特征值
-
(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { NSLog(@"—–发现特征值"); //在这里给 蓝牙设备写数据, 或者将 peripheral 和 characteristic 拿出去,可以在其他地方,发送命令 if (error == nil) { for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"发现特征值:%@", characteristic); //这里只写了 devicePeripheral 的特征值。 手环的 方法同理,代码几乎一样 if (_devicePeripheral == peripheral) { [peripheral setNotifyValue:YES forCharacteristic:characteristic]; //以下宏定义的UUID 请根据自己当前的硬件设备做调整。 不同的设备会有不同的定义。 //另外,读写的,也会的也会不同。 可以使用 第三方蓝牙工具,进行设备上的服务和特征值查看一下。 //或者是直接参阅 贵公司的蓝牙设备 协议文档 if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUID_DEVICE_SERVER_1]]) { //如果是指定的特征值,设置NotifyValue [peripheral setNotifyValue:YES forCharacteristic:characteristic]; }else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUID_DEVICE_SERVER_2]]) { _deviceCharacteristic = characteristic; for (id listener in _listener) { if ([listener respondsToSelector:@selector(didDiscoverDevicePeripheral:service:)]) { [listener didDiscoverDevicePeripheral:peripheral service:service]; } } } }else if (_wristbandPeripheral == peripheral) { } }
} }
#pragma mark - » 如果一个特征的值被更新,然后周边代理接收
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
}
#pragma mark - » 读数据
//这里是接收到蓝牙数据。 但是蓝牙数据都是一堆 16进制数据,需要根据协议去解析
//数据协议,请参阅协议文档,如果没有,就去找吧。
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(@"接收到数据:%@,%@", peripheral.name, characteristic.value);
}
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(@"did write value For Characteristic");
NSLog(@"%@", characteristic.value);
}
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error {
NSLog(@"did Write Value For Descriptor");
}