最近这段时间在研究蓝牙,也研究了一段时间了现在在下面做个总结
1 其实蓝牙连接只要明白了整体原理,其实挺简单的
2 大部分情况下,手机作为中心管理者,而连接的设备被称为外设,外设的结构有点像一颗大树,外设我把它看成是大叔的树干,然后由树干向上生成生成许多树干分支,这些分支就是服务,分支上面在分的小分支就是特征,而小树枝上面的职业可以看成是特征的描述。
3 然后就需要知道哪根树枝为你服务了,苹果取名字为服务,那就是为你服务的,所以你需要知道是哪跟树枝为你服务
知道了哪根树枝之后就需要分析这根树枝上的小枝干到底是是些什么功能,其实这些小枝干就是所谓的"特征"
然后根据硬件工程师提供的UUID 记录下可以读取信息的特征,对这个特征监听它的值的变化。
4 同样的根据硬件工程师提供的UUID 记录下可以写入信息额特征,方便后期对特征进行数据命令写入来操作蓝牙设备。蓝牙大体就这样一个流程了,下面说下代码如何一步一步实现上述过程
1. 首先是想要导入蓝牙需要的头文件 CoreBluetooth
然后实例化中心管理者
self.manger=[[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
中心管理者实例化了会自动触发监测蓝牙状态的代理
/* CBManagerStateUnknown = 0, CBManagerStateResetting, CBManagerStateUnsupported, CBManagerStateUnauthorized, CBManagerStatePoweredOff, CBManagerStatePoweredOn, 监测蓝牙状态 */ -(void)centralManagerDidUpdateState:(CBCentralManager *)central{ switch (central.state) { case CBManagerStatePoweredOn: { NSLog(@"蓝牙已开启"); [self.manger scanForPeripheralsWithServices:nil options:nil]; } break; case CBManagerStatePoweredOff:{ } break; default: break; } }
在蓝牙开启的情况下去扫描周围的蓝牙设备 然后扫描到了设备会调用到下面的方法
#pragma mark 扫描 发现周围设备 -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{ NSLog(@"%@===%ld",peripheral.name,(long)peripheral.state); //发现需要的设备 进行蓝牙连接 if ([peripheral.name rangeOfString:@"BP826"].length!=0) { self.pheral=peripheral; [self.manger connectPeripheral:peripheral options:nil]; [central stopScan]; } }
找到对应的蓝牙设备进行蓝牙连接 成功、失败、断开连接会有下面回调
#pragma mark 连接成功对应设备 -(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{ // self.pheral=peripheral; peripheral.delegate=self; [peripheral discoverServices:nil]; NSLog(@"连接上了对应的设备"); } #pragma mark 断开连接 -(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ } #pragma mark 连接失败 失败 -(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ }
成功连接上外设之后就是去发现外设里面的服务 [peripheral discoverServices:nil];
然后发现服务会调用下面的方法 找到你需要的那个服务,然后再去发现你的那个服务中的特征
#pragma mark 发现服务 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ for (CBService *service in peripheral.services) { if ([service.UUID.UUIDString isEqualToString:kSERVICEUUID]) { [peripheral discoverCharacteristics:nil forService:service]; } } }
然后就回去寻找服务中的特征 然后根据硬件提供给你的读取或者写入的特征ID去找到对应的特征 然后记录下来
并对读取的特征进行特征值变化的监听
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{ for (CBCharacteristic *character in service.characteristics) { if ([character.UUID.UUIDString isEqualToString:kread_UUID]) { self.readCharacter=character; //开启特征值变化监听 值变化了会调用 peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error [peripheral setNotifyValue:YES forCharacteristic:character]; } if ([character.UUID.UUIDString isEqualToString:kwrite_UUID]) { self.writeCharater=character; } } }
然后特征值发生变化了会调用到下面的方法
#pragma mark 特征值发生变化 -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ NSLog(@"%@",characteristic.value); }
如果你想对硬件操作 那么你需要给写入的那个特征写入值 需要调用
[self.pheral writeValue:[self convertHexStrToData:@"A0A0A0A0A0A0A0"] forCharacteristic:self.writeCharater type:CBCharacteristicWriteWithResponse]; //字符串命令装换成NSData类型 - (NSData *)convertHexStrToData:(NSString *)str { if (!str || [str length] == 0) { return nil; } NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8]; NSRange range; if ([str length] % 2 == 0) { range = NSMakeRange(0, 2); } else { range = NSMakeRange(0, 1); } for (NSInteger i = range.location; i < [str length]; i += 2) { unsigned int anInt; NSString *hexCharStr = [str substringWithRange:range]; NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr]; [scanner scanHexInt:&anInt]; NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1]; [hexData appendData:entity]; range.location += range.length; range.length = 2; } return hexData; }
到此为止整个蓝牙设备基础的功能就列举完了 这也是自己这段时间研究小小的成果吧 fighting!