文章目录
iOS 蓝牙设备
一、 蓝牙管理类的初始化
二、检查外部蓝牙设备是否可用
三、开始扫描蓝牙设备
四、结束蓝牙设备扫描
四、连接指定设备
五、连接蓝牙设备后接收蓝牙服务
1.发现服务后回调订阅指定`Service`的特征
2. 发现订阅的特征触发方法
3.当设备特征值变化时触发方法(read 和notify 状态)
4.给设备写入数据成功触发方法
iOS 蓝牙设备
一、 蓝牙管理类的初始化
CBCentralManager *blueManager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:nil];
1
二、检查外部蓝牙设备是否可用
在CBCentralManager初始化之后会自动调用centralManagerDidUpdateState,在蓝牙的状态为开即centralManager.state == CBManagerStatePoweredOn 时,进行蓝牙扫描。
– (void)centralManagerDidUpdateState:(CBCentralManager *)central{
if (central.state == CBManagerStatePoweredOn) {
[weakManager startScan];
}
}

三、开始扫描蓝牙设备
扫描指定UUID 的设备,在options 里面配置是否允许重复的key,当services入参为空值时,默认扫描所有设备。
[self.blueManager scanForPeripheralsWithServices:@[] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]}];
四、结束蓝牙设备扫描
在扫描完成蓝牙设备之后,要及时关闭蓝牙扫描
[CBCentralManager stopScan];
1
四、连接指定设备
在正确扫描设备之后需要在CBCentralManagerDelegate实现其中的发现设备代理,用户可以在发现代理中进行数据的去重和回调操作。
– (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
if (central) {
DeviceModel *model = [[DeviceModel alloc] init];
model.deviceName = peripheral.name;
model.rssid = RSSI;
NSLog(@”peripheral%@–%@–%@”, peripheral.name, peripheral.identifier, RSSI);
[self.deviceArray addObject:model];
}
}

连接蓝牙设备
[CBCentralManager connectPeripheral:HWBleMgr.model.discoveredPeripheral options:nil];
1
五、连接蓝牙设备后接收蓝牙服务
在连接成功之后需要遵守CBPeripheral类的代理方法CBPeripheralDelegate,并实现相关方法。
– (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
peripheral.delegate = self;
// 设置指定发现的服务集合,如果设置发现服务为nil,则所有的相关服务都会被发现,当服务被发现时会回调
`didDiscoverServices`方法。
[peripheral discoverServices:nil];
// 可以在这个代理中监听一下蓝牙的连接状态
}

1.发现服务后回调订阅指定Service的特征
– (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
NSMutableArray *services = [NSMutableArray array];
for (CBService *s in self.model.discoveredPeripheral.services) {

NSString *uuid = [NSString stringWithFormat:@”%@”,[s.UUID UUIDString]?:@””];
[services addObject:uuid];
// 订阅特征
[self.model.discoveredPeripheral discoverCharacteristics:nil forService:s];
}

NSDictionary *dict = @{@”services”:services,
@”isPrimary”:[NSNumber numberWithBool:YES]
};
//
if (self.model.deviceServicesCallbackBody.callbacks.count > 0) {

[self.model.deviceServicesCallbackBody callWithMyArguments:@[dict]];
}
}

2. 发现订阅的特征触发方法
发现特征后,可以根据特征的properties 进行:读(read)、写(writeValue)、订阅通知(setNotifyValue)、扫描特征的描述(discoverDescriptorsForCharacteristic)
– (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{

for (CBCharacteristic *c in service.characteristics) {
NSString *uuid = [NSString stringWithFormat:@”%@”,[c.UUID UUIDString]];
BOOL isRead = NO;
BOOL isWrite = NO;
BOOL isNotify = NO;
BOOL isIndicate = NO;
if(c.properties == CBCharacteristicPropertyRead){
isRead = YES;
}else if (c.properties == CBCharacteristicPropertyWrite) {
isWrite = YES;
}else if (c.properties == CBCharacteristicPropertyNotify) {
isNotify = YES;
}else if (c.properties == CBCharacteristicPropertyIndicate) {
isIndicate = YES;
}
NSDictionary *properties = @{@”read”:[NSNumber numberWithBool:isRead],
@”write”:[NSNumber numberWithBool:isWrite],
@”notify”:[NSNumber numberWithBool:isNotify],
@”indicate”:[NSNumber numberWithBool:isIndicate]
};
NSDictionary *dict = @{@”uuid”:uuid,
@”properties”:properties
};

if (![self.model.connectedPeripheralCharacteristics containsObject:dict]) {

[self.model.connectedPeripheralCharacteristics addObject:dict];
}

// [_model.discoveredPeripheral setNotifyValue:YES forCharacteristic:c];
}

// 判断返回的characteristics次数,确定是*后一次,即读取完毕才callback
if (peripheral.services.count == _discoveredCharacteristicsCount) {

_discoveredCharacteristicsCount = 1;

NSArray *characteristics = self.model.connectedPeripheralCharacteristics;
if (self.model.deviceCharacteristicsCallbackBody.callbacks.count > 0) {

[self.model.deviceCharacteristicsCallbackBody callWithMyArguments:characteristics];
}

if (self.model.servicesDiscoveredCallbackBody.callbacks.count > 0) {

NSString *callbackString = [self.model.servicesDiscoveredCallbackBody.callbacks firstObject];
NSString *returnStr = [NSString stringWithFormat:@”%@(‘%@’)”,callbackString,@0];
dispatch_async(dispatch_get_main_queue(), ^{

[[NSNotificationCenter defaultCenter]postNotificationName:@”HWBluetoothCallbackBodyNotification” object:returnStr];
});
}
}else {
_discoveredCharacteristicsCount ++;
}
}

3.当设备特征值变化时触发方法(read 和notify 状态)
– (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {

}

– (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
if (characteristic.isNotifying) {
[peripheral readValueForCharacteristic:characteristic];
} else {
NSLog(@”Notification stopped on %@. Disconnecting”, characteristic);
NSLog(@”%@”, characteristic);
[self.centralManager cancelPeripheralConnection:peripheral];
}
}

4.给设备写入数据成功触发方法
– (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
NSLog(@”写入成功”);
if ([self.delegate respondsToSelector:@selector(didWriteSucessWithStyle:)]) {
[self.delegate didWriteSucessWithStyle:_style];
}
}