最近做了一个蓝牙的app,所以就来梳理了一下自己的蓝牙开发步骤及方式,如有不对,欢迎指出。
第一步
导入CoreBluetooth.framework库
*第二步 *
在项目中合适的地方导入头文件
import
并遵循两个代理
第三步
初始化CBCentralManager对象
//(PS:设为nil表示在主线程中执行)
manager = [CBCentralManager alloc] initWithDelegate:self queue:nil];
第四步
执行代理方法,此方法在设置完代理后就会执行
-(void)centralManagerDidUpdateState:(CBCentralManager *)central {
//判断当前蓝牙状态
switch (central.state) {
case CBCentralManagerStateUnknown:
DWLog(@"未知状态");
break;
case CBCentralManagerStateUnsupported:
DWLog(@"模拟器不支持蓝牙调试");
break;
case CBCentralManagerStateUnauthorized:
break;
case CBCentralManagerStatePoweredOff:
DWLog(@"蓝牙处于关闭状态");
break;
case CBCentralManagerStateResetting:
break;
case CBCentralManagerStatePoweredOn:
DWLog(@"蓝牙已开启");
//NO表示不会重复搜索以搜索到到设备
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
//当得知蓝牙为开启状态时,直接搜索周围的蓝牙设备
//开始搜索蓝牙
[manager scanForPeripheralsWithServices:nil options:options];
break;
}
}
第五步
搜索到蓝牙会调用此方法,可以在此方法里设置搜索过滤规则
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
//此处设置需要的过滤规则
if ([peripheral.name isEqualToString:@"dwang"]) {
//将符合要求的设备进行数据持久化,以便下面连接的时候使用
self.activePeripheral = peripheral;
DWLog(@"peripheral.name===%@",peripheral.name);
}
}
第六步
连接蓝牙
[manager connectPeripheral:self.activePeripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
连接成功的回调
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
//连接成功后,设置设备的代理
peripheral.delegate = self;
//查找服务
[peripheral discoverServices:nil];
}
连接失败的回调
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
DWLog(@"连接失败%@",error);
}
第七步
扫描外设中的服务值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if ([peripheral isEqual:self.activePeripheral]) {
for (CBService *services in peripheral.services) {
if ([[services UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的服务UUID"]]) {
读服务对象 = services;
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"接收数据的特征值UUID"],[CBUUID UUIDWithString:@"发送数据的特征值UUID"]] forService:读服务对象];
} else if ([[services UUID] isEqual:[CBUUID UUIDWithString:@"发送数据的服务UUID"]]) {
写服务对象 = services;
[peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"接收数据的特征值UUID"],[CBUUID UUIDWithString:@"发送数据的特征值UUID"]] forService:写服务对象];
}
}
}
}
获取外设中的特征值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {
if ([peripheral isEqual:self.activePeripheral]){
// 新建特征值数组
NSArray *characteristics = [service characteristics];
DWLog(@"characteristics=%@",characteristics);
CBCharacteristic *characteristic;
if ([[service UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的服务UUID"]]) {
for (characteristic in characteristics) {
DWLog(@"发现特值UUID: %@\n", [characteristic UUID].data);
if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:@"发送数据的特征值UUID"]]) {
写特征值对象 = characteristic;
} else if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的特征值UUID"]]) {
读特征值对象 = characteristic;
//订阅特征值通知
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
}
}
}
DWLog(@"%s\n\
连接%@设备成功\n\
Services==%lu\n\
发现服务UUID:\n\
service.UUID.data==%@\n\
service.UUID==%@\n\
characteristic==%@\n\
identifier==%@\n\
name==%@\n\
state==%ld,",
__func__,
peripheral.name,
peripheral.services.count,
service.UUID.data,
service.UUID,
service.characteristics,
service.peripheral.identifier,
service.peripheral.name,
(long)service.peripheral.state);
}
订阅的特征值发生改变会调用此方法
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
DWLog(@"%@,----%@",[characteristic UUID],[characteristic value]);
}
只要蓝牙设备更新特征值就会调用此方法,此方法一般是只要连接上蓝牙设备就会一直调用
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
DWLog(@"%@---uuid====%@---value===%@",peripheral.name,[characteristic UUID],characteristic.value);
}
第八步
发送数据
//一般数据发送给蓝牙的数据都是字节数据,这就需要看你们之间的协议了,在这里我就直接用字节举例
Byte byte[] = {
1, 2, 3, 4, 5,
6, 7, 8, 9, 10,
11, 12, 13, 14, 15,
16, 17, 18, 19, 20
};
////蓝牙一次最多只能接收20字节的数据,超过20字节就需要分段发送,否则无法发送成功。也许会在发送完成后的回调方法中出现没有写入权限的错误
NSData *data = [NSData dataWithBytes:byte length:20];
//type:需要知道蓝牙外设的类型,否则无法成功发送数据,并且如果使用CBCharacteristicWriteWithoutResponse就不会走发送数据的回调
[self.activePeripheral writeValue:data forCharacteristic:写特征值对象 type:CBCharacteristicWriteWithoutResponse];
数据发送之后的回调
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
DWLog(@"完成数据写入===%@ ---- characteristic.UUID==%@", characteristic.value, characteristic.UUID);
DWLog(@"数据发送失败===error: %@", error);
}
这里有一个我写的Demo:如需使用只需要改一些必要参数就可以了
OK
圆满结束
欢迎各位加我QQ:739814184一同讨论,一同进步
也可以扫描二维码加我微信
4DBF63071DCD3695DD0E205DDC04132E.png