IOS ble蓝牙,重连蓝牙,重新获取CBPeripheral未空

//
// BleUtil.m
// yu
//
// Created by CharkWong on 2019/5/14.
// Copyright © 2019 CharkWong. All rights reserved.
//

#import “BleUtil.h”

#import “…/context/DataBox.h”
NSString const SERVICE_UUID = @"6E400001-B5A3-F393-E0A9-E50E24DCC**";
NSString const TX_WRITE_UUID = @"6E400002-B5A3-F393-E0A9-E50E24DC***";
NSString const RX_NOTIFY_UUID = @"6E400003-B5A3-F393-E0A9-E50E2***A9E";
@interface BleUtil ()<CBCentralManagerDelegate,CBPeripheralDelegate>
//手机
@property(nonatomic,strong)CBCentralManager *centralManager;
//蓝牙外设
@property(nonatomic,strong)CBPeripheral *peripheral;
//扫描外设数组
@property(nonatomic,strong)NSMutableArray<CBPeripheral *> *scanArr;
//写入外设回调
@property(nonatomic,copy)NSMutableData *(^writeBlock)(void);
//连接外设回调
@property(nonatomic,copy)void(^connectBlock)(NSError *);
@end

@implementation BleUtil

//单例

  • (instancetype)getSingleton {
    static BleUtil *_sharedSingleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    // 要使用self来调用
    _sharedSingleton = [[self alloc] init];
    // centralMgr = [_sharedSingleton getCentralMgr];
    });
    return _sharedSingleton;
    }

-(CBCentralManager *)centralManager{
if(_centralManager == nil){
//创建蓝牙
_centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
}
return _centralManager;
}

//检测蓝牙是否可用

  • (BOOL)availableBluethooth
    {
    CBManagerState state = [self.centralManager state];
    /**
    CBManagerStateUnknown = 0,未知(第一次启动蓝牙中心是未知状态)
    CBManagerStateResetting,蓝牙不可用 (未知错误)
    CBManagerStateUnsupported,当前手机不支持蓝牙
    CBManagerStateUnauthorized,//未授权
    CBManagerStatePoweredOff,//蓝牙关闭
    CBManagerStatePoweredOn,//蓝牙可用
    */
    BOOL flag = NO;
    NSString *stateStr;
    switch (state) {
    case CBManagerStateUnknown:
    stateStr = @“第一次启动蓝牙”;
    flag = YES;
    break;
    case CBManagerStateResetting:
    stateStr = @“蓝牙不可用”;
    break;
    case CBManagerStateUnsupported:
    stateStr = @“蓝牙未授权”;
    break;
    case CBManagerStatePoweredOff:
    stateStr = @“蓝牙关闭”;
    //实际开发中可以给用户一个弹窗提示 点击跳转到系统蓝牙设置界面
    break;
    case CBManagerStatePoweredOn:
    flag = YES;
    stateStr = @“蓝牙可用”;

          break;
      default:
          break;
    

    }
    NSLog(@“BleUtil stateStr=%@”,stateStr);
    return flag;
    }

#pragma mark -连接外设

  • (void)connectPeripheral:(void(^)(NSError *))connBlock Completion:(NSMutableData *(^)(void))writeBlock
    {
    NSAssert([self availableBluethooth] == YES, @“BleUtil当前蓝牙不可用,请检查蓝牙状态”);

    NSString *uuidStr = [DataBox getBlePeripheralsUUID];
    if(uuidStr == nil){
    NSLog(@“UUID为空!”);
    return;
    }
    //[self.centralManager scanForPeripheralsWithServices:nil options:nil];
    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:uuidStr];
    NSArray *arr = [self.centralManager retrievePeripheralsWithIdentifiers:[NSArray arrayWithObject:uuid]];
    CBPeripheral *per = [arr lastObject];
    // CBPeripheral *per = nil;
    // for(CBPeripheral *pera in _scanArr){
    // if([pera.identifier.UUIDString isEqualToString:uuidStr]){
    // per = pera;
    // break;
    // }
    // }
    if(per == nil){
    NSLog(@“找不到蓝牙设备!”);
    return;
    }
    NSLog(@“state:%ld==%ld”,(long)per.state,(long)CBPeripheralStateDisconnected);
    if(per.state == CBPeripheralStateDisconnected){
    [self.centralManager connectPeripheral:per options:nil];
    }
    //保存连接回调
    self.connectBlock = connBlock;
    self.writeBlock = writeBlock;
    }

//发现蓝牙设备监听

  • (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
    {
    NSString *perName = peripheral.name;

    if(perName == nil){
    return;
    }
    NSLog(@“扫描成功,发现蓝牙设备!”);
    if (self.scanArr == nil) {
    self.scanArr = [[NSMutableArray alloc] init];
    }
    if([_scanArr containsObject:peripheral]){
    return;
    }
    [_scanArr addObject:peripheral];
    }

//已连接蓝牙设备监听

  • (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
    NSLog(@“BleUtil已经连接设备:%@”, peripheral.name);
    if (self.connectBlock) {
    self.connectBlock(nil);
    }
    [self.centralManager stopScan];
    //1.先保存外设
    self.peripheral = peripheral;
    //2.设置外设的代理
    self.peripheral.delegate = self;

    #pragma mark -流程4 开发发现外设的服务
    //如果没有寻找服务的话,外设的服务数组是空
    //3.寻找外设的服务,为nil则表示寻找所有的服务
    [self.peripheral discoverServices:nil];
    // for (CBService *service in peripheral.services) {
    // // 找到对应的服务
    // if ([service.UUID isEqual:[CBUUID UUIDWithString:SERVICE_UUID]]) {
    // // 查找特征
    // [peripheral discoverCharacteristics:nil forService:service];
    // break;
    // }
    // }
    // //搜索服务
    // NSMutableData *data=[[NSMutableData alloc] initWithCapacity:0];
    // int8_t byte0 = 0x51;
    // [data appendBytes:&byte0 length:sizeof(byte0)];
    // int8_t byte1 = 0x01;
    // [data appendBytes:&byte1 length:sizeof(byte1)];
    // int8_t byte2 = 0x01;
    // [data appendBytes:&byte2 length:sizeof(byte2)];
    // //写入
    // [peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
    }

//连接蓝牙设备监听失败

  • (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
    {
    NSLog(@“蓝牙连接失败:%@”,error);
    if (self.connectBlock) {
    self.connectBlock(error);
    }
    }

//发现服务监听

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error
    {
    NSLog(@“BleUtil发现服务!”);
    for (CBService *service in peripheral.services) {
    // 找到对应的服务
    if ([service.UUID isEqual:[CBUUID UUIDWithString:SERVICE_UUID]]) {
    // 查找特征
    [peripheral discoverCharacteristics:nil forService:service];
    break;
    }
    }
    }

//发现特征值监听

  • (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
    {
    for (CBCharacteristic *chara in service.characteristics) {
    if ([[chara UUID] isEqual:[CBUUID UUIDWithString:TX_WRITE_UUID]]){
    NSMutableData *data = nil;
    if (self.writeBlock) {
    data = self.writeBlock();
    }
    if(data != nil){
    //写入
    [peripheral writeValue:data forCharacteristic:chara type:CBCharacteristicWriteWithResponse];
    //NSLog(@“找到可写特征: %@”, chara);
    NSLog(@“BleUtil开始写入成功!”);
    }else{
    NSLog(@“BleUtil开始写入失败!”);
    }

      }
      if ([[chara UUID] isEqual:[CBUUID UUIDWithString:RX_NOTIFY_UUID]]){
          
          // 监听外设特征值
          [peripheral setNotifyValue:YES forCharacteristic:chara];
          // 读取特征数据
          [peripheral readValueForCharacteristic:chara];
          //NSLog(@"找到可读特征 : %@", chara);
      }
    

    }
    }

//向peripheral中写入数据后的回调函数

  • (void)peripheral:(CBPeripheral*)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    NSLog(@“BleUtil写入成功: %@”, characteristic.value);
    }

#pragma mark- 获取外设发来的数据,不论是read和notify,获取数据都是从这个方法中读取。

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    {
    NSLog(@“外设发送过来的数据:%@”,characteristic.value.description );
    }

#pragma mark- 中心读取外设实时数据

  • (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {

    }

    if (characteristic.isNotifying) {
    //读取外设数据
    [peripheral readValueForCharacteristic:characteristic];
    NSLog(@“BleUtil%@”,characteristic.value);
    } else {

    }
    }

  • (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {
    switch (central.state) {
    case CBManagerStateUnknown:
    {
    NSLog(@“BleUtil无法获取设备的蓝牙状态”);
    }
    break;
    case CBManagerStateResetting:
    {
    NSLog(@“BleUtil蓝牙重置”);
    }
    break;
    case CBManagerStateUnsupported:
    {
    NSLog(@“BleUtil该设备不支持蓝牙”);
    }
    break;
    case CBManagerStateUnauthorized:
    {
    NSLog(@“BleUtil未授权蓝牙权限”);
    }
    break;
    case CBManagerStatePoweredOff:
    {
    NSLog(@“BleUtil蓝牙已关闭”);
    }
    break;
    case CBManagerStatePoweredOn:
    {
    NSLog(@“BleUtil蓝牙已打开”);
    }
    break;

      default:
      {
          NSLog(@"BleUtil未知的蓝牙错误");
      }
          break;
    

    }
    }

@end

如果蓝牙已连接成功,再重新扫描蓝牙并尝试连接,找到的蓝牙CBPeripheral为空,不能再重复使用CBPeripheral。只有把连接好的CBPeripheral放到外部全局变量中,让其他类访问。

发布了138 篇原创文章 · 获赞 83 · 访问量 88万+

猜你喜欢

转载自blog.csdn.net/kunga0814/article/details/90257085