开头
BabyBluetooth
蓝牙开发步骤
- 扫描外设
- 发现外设
- 连接外设
- 获取外设读写特征
- 获取外设发出的信息和向外设发信息
基本使用
- 这里的案例是我最近的蓝牙项目,通过
tableView
显示被扫描到的设备,中心设备连接一个蓝牙设备,通过写特征值进行发数据,通过监听特征值进行消息监听
- 创建baby对象
self.baby = [BabyBluetooth shareBabyBluetooth]
self.baby.scanForPeripherals().begin();
[self.baby cancelScan];
[self.baby cancelAllPeripheralsConnection];
self.baby.having(pp).and.then.connectToPeripherals().discoverServices().discoverCharacteristics().readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();
[self.connectPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithResponse];
[self babyDelegate]
__weak typeof(self) weakSelf = self;
[self.baby setBlockOnCentralManagerDidUpdateState:^(CBCentralManager *central) {
if (central.state == CBManagerStatePoweredOn) {
[SVProgressHUD showInfoWithStatus:@"设备打开成功,开始扫描设备"];
}
NSLog(@"%@", central);
}];
[self.baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
if (![weakSelf.peripheralArray containsObject:peripheral]) {
[weakSelf.peripheralArray addObject:peripheral];
if ([weakSelf.delegate respondsToSelector:@selector(reloadData)]) {
[weakSelf.delegate reloadData];
}
}
NSLog(@"%@", weakSelf.peripheralArray);
}];
[self.baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
[SVProgressHUD showInfoWithStatus:@"连接成功"];
weakSelf.connectPeripheral = peripheral;
}];
[self.baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
}];
[self.baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
NSLog(@"service name: %@", service);
NSLog(@"service uuidstring name: %@", service.UUID.UUIDString);
NSLog(@"%@", service.characteristics);
if([service.UUID.UUIDString isEqualToString:@"6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]) {
for (CBCharacteristic * tempChara in service.characteristics) {
NSLog(@"%@", tempChara);
if ([tempChara.UUID.UUIDString isEqualToString:@"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"]) {
weakSelf.notifyCharacteristic = tempChara;
NSLog(@"self.notifyCharacteristic : %@", weakSelf.notifyCharacteristic);
[weakSelf.baby notify:peripheral characteristic:weakSelf.notifyCharacteristic block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
NSLog(@"notify %@", characteristics.value);
NSLog(@"notify Str %@", [[NSString alloc] initWithData:characteristics.value encoding:NSUTF8StringEncoding]);
[weakSelf handleData:characteristics.value];
}];
}
else if ([tempChara.UUID.UUIDString isEqualToString:@"6E400002-B5A3-F393-E0A9-E50E24DCCA9E"]) {
weakSelf.writeCharacteristic = tempChara;
NSLog(@"self.writeCharacteristic : %@", weakSelf.writeCharacteristic);
}
}
}
}];
[self.baby setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
if (peripheralName.length >0) {
return YES;
}
return NO;
}];
[self.baby setBlockOnDidWriteValueForCharacteristic:^(CBCharacteristic *characteristic, NSError *error) {
[SVProgressHUD showSuccessWithStatus:@"写入成功"];
[SVProgressHUD dismissWithDelay:1];
}];
[self.baby setBlockOnDisconnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
[SVProgressHUD showInfoWithStatus:@"断开链接"];
[SVProgressHUD dismissWithDelay:1];
if ([weakSelf.delegate respondsToSelector:@selector(disconnect)]) {
[weakSelf.delegate disconnect];
}
}];
[self.baby setBlockOnCancelAllPeripheralsConnectionBlock:^(CBCentralManager *centralManager) {
NSLog(@"setBlockOnCancelAllPeripheralsConnectionBlock");
}];
[self.baby setBlockOnCancelScanBlock:^(CBCentralManager *centralManager) {
NSLog(@"setBlockOnCancelScanBlock");
}];
NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES};
NSDictionary *connectOptions = @{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES,
CBConnectPeripheralOptionNotifyOnDisconnectionKey:@YES,
CBConnectPeripheralOptionNotifyOnNotificationKey:@YES};
[self.baby setBabyOptionsWithScanForPeripheralsWithOptions:scanForPeripheralsWithOptions
connectPeripheralWithOptions:connectOptions
scanForPeripheralsWithServices:nil
discoverWithServices:nil
discoverWithCharacteristics:nil];
数据转换
- 对于蓝牙外设来说,一般的数据为16进制的,所以会涉及到数据格式的转换,而对于iOS来说,便于处理的数据格式肯定是数据,可以根据帧结构进行不同的处理
- 这个数组中的每个元素都以NSNumber的形式存储
- NSArray转成NSData
- (NSData *)convertArrayToDataWithArray:(NSArray *)array {
NSUInteger len = array.count
UInt8 buffer[len]
for (int i = 0
{
buffer[i] = [[array objectAtIndex:i] unsignedCharValue]
}
NSData *data = [NSData dataWithBytes:buffer length:len]
return data
}
- (NSArray *)convertDataToArrayWithData:(NSData *)data{
//把读到的数据复制一份
NSData *recvBuffer = [NSData dataWithData:data]
NSUInteger recvLen = [recvBuffer length]
UInt8 *recv = (UInt8 *)[recvBuffer bytes]
if (recvLen > 1000) {
return nil
}
//把接收到的数据存放在recvData数组中
NSMutableArray *recvData = [[NSMutableArray alloc] init]
NSUInteger j = 0
while (j < recvLen) {
[recvData addObject:[NSNumber numberWithUnsignedChar:recv[j]]]
j++
}
return recvData
}
[dataArr addObject:[NSNumber numberWithUnsignedInteger:0x00]]
[dataArr[0] unsignedIntValue] == 0x81
总结
- 这里仅仅进行的单设备连接,据说可以进行多设备连接,找机会把坑补上
- 以上总结的仅仅是我在项目中的用到的状态,还可以监听挺多蓝牙状态的,挖个坑
- 具体使用上,是封装了一层Manager管理类。