文章目录
-
-
-
- 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];
二、检查外部蓝牙设备是否可用
- 在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];
四、连接指定设备
- 在正确扫描设备之后需要在
CBCentralManagerDelegate
实现其中的发现设备代理,用户可以在发现代理中进行数据的去重和回调操作。
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)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];
五、连接蓝牙设备后接收蓝牙服务
- 在连接成功之后需要遵守
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];
}
}