iOS 蓝牙设备

iOS 蓝牙设备

1、 蓝牙管理类的初始化
CBCentralManager *blueManager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) options:nil];
2、检查外部蓝牙设备是否可用
  • 在CBCentralManager初始化以后会自动调用centralManagerDidUpdateState,在蓝牙的状态为开即centralManager.state == CBManagerStatePoweredOn 时,进行蓝牙扫描。
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    if (central.state == CBManagerStatePoweredOn) {
            [weakManager startScan];
        }
}
3、开始扫描蓝牙设备
  • 扫描指定UUID 的设备,在options 里面配置是否容许重复的key,当services入参为空值时,默认扫描全部设备。
    [self.blueManager scanForPeripheralsWithServices:@[] options:@{CBCentralManagerScanOptionAllowDuplicatesKey:[NSNumber numberWithBool:YES]}];
4、结束蓝牙设备扫描
  • 在扫描完成蓝牙设备以后,要及时关闭蓝牙扫描
[CBCentralManager stopScan];
4、链接指定设备
  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];
    }
}
  1. 链接蓝牙设备
[CBCentralManager connectPeripheral:HWBleMgr.model.discoveredPeripheral options:nil];
5、链接蓝牙设备后接收蓝牙服务
  • 在链接成功以后须要遵照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];
    }
}