蓝牙使用 iOS小结

做了一个单例
h文件

#import 
#import 
NS_ASSUME_NONNULL_BEGIN
typedef void(^DidRefreshPeripherals)(void);
typedef void(^CentralManagerDidUpdateState)(CBManagerState state);
typedef void(^DidConnectPeripheral)(void);
typedef void(^DidFailToConnectPeripheral)(void);
typedef void(^DidDisconnectPeripheral)(void);

typedef void(^DidDiscoverServicesErr)(NSError *err);
typedef void(^GetConnectionStatus)(NSString *connectionStatus);


typedef void(^DidReceiveMSG)(int value);
@interface BluetoothCenter : NSObject
@property(strong,nonatomic) CBCentralManager *centerManager;//--------中心设备管理器

@property(strong,nonatomic) NSMutableArray *peripherals;//------------所有蓝牙外设

@property(strong,nonatomic) NSDictionary *currentPeripheral;//----------当前连接的外设

@property(copy)CentralManagerDidUpdateState centralManagerDidUpdateState;

@property(copy)DidRefreshPeripherals didRefreshPeripherals;

@property(copy)DidConnectPeripheral didConnectPeripheral;
@property(copy)DidFailToConnectPeripheral didFailToConnectPeripheral;
@property(copy)DidDisconnectPeripheral didDisconnectPeripheral;

@property(copy)DidDiscoverServicesErr didDiscoverServicesErr;

@property(copy)DidReceiveMSG didReceiveMSG;

@property (nonatomic ,assign) BOOL switchStatus;

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
- (id)copy NS_UNAVAILABLE; // 没有遵循协议可以不写
- (id)mutableCopy NS_UNAVAILABLE; // 没有遵循协议可以不写

+ (instancetype)sharedCenter;
//第四步:连接蓝牙设备
- (void)connectPeripheral:(CBPeripheral *)peripheral;
- (void)startScanPeripheral;
- (void)stopScanPeripheral;

@end

NS_ASSUME_NONNULL_END

m文件



#import "BluetoothCenter.h"

@implementation BluetoothCenter
// 跟上面的方法实现有一点不同
+ (instancetype)sharedCenter {
    static BluetoothCenter *_sharedSingleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
          // 要使用self来调用
        _sharedSingleton = [[self alloc] init];
        [_sharedSingleton initCBCentralManager];
    });
    return _sharedSingleton;
}
#pragma mark  =====  init  =====
/*第一步:创建设备管理器
 创建完之后,会回掉CBCentralManagerDelegate中的方法:- (void)centralManagerDidUpdateState:(CBCentralManager *)central
 */



-(void)initCBCentralManager
{
    self.centerManager = [[CBCentralManager alloc] init];
    self.centerManager = [self.centerManager initWithDelegate:self queue:nil];
    self.peripherals = [NSMutableArray array]; //存放所有扫描到的蓝牙外设
    NSLog(@"self.centerManager ===== %@",self.centerManager);
}

- (void)startScanPeripheral
{
    
    
    if (self.centerManager.state == CBManagerStatePoweredOn)
    {
        //扫描蓝牙设备
        [self.centerManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(NO)}];
        //key值是NSNumber,默认值为NO表示不会重复扫描已经发现的设备,如需要不断获取最新的信号强度RSSI所以一般设为YES了
        
    }
    
}

- (void)stopScanPeripheral
{

    if ([self.centerManager isScanning])
    {
        [self.centerManager stopScan];
//        [ToolBox noticeContent:@"扫描结束" andShowView:self.view andyOffset:NoticeHeight];
    }

}

//外设管理器状态发生变化,初始化centerManger后,会走这里
-(void)centralManagerDidUpdateState:(CBCentralManager *)central
{
     
    if (self.centralManagerDidUpdateState) {
        self.centralManagerDidUpdateState(central.state);
    }
    
}

#pragma mark  =====  CBCentralManagerDelegate  =====
/*第三步:扫描完成,将发现设备的不重复地添加到外设数组中
 这个代理方法每扫描到一个外设,就会进入一次。
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI//RSSI信号强度
{
    
    NSString *locolName = [advertisementData objectForKey:@"kCBAdvDataLocalName"];//广播的名称(准确)
    NSString *peripheralName = peripheral.name;//设备名称 (修改过的名称获取不到)
    
    NSLog(@"locolName%@\n Discovered name:%@\n identifier:%@\n advertisementData:%@\n RSSI:%@\n state:%ld\n",locolName,peripheral.name, peripheral.identifier,advertisementData,RSSI,(long)peripheral.state);
  
    
    locolName = locolName == nil ? @"" : locolName;
    peripheralName = peripheralName == nil ? @"" : peripheralName;
    
    
    #warning --做剔除--
    NSString * name = locolName.length == 0 ? peripheralName : locolName;
    if (![name containsString:@"xxxxxx"] ){
        return;
    }else{
       
        [self connectPeripheral:peripheral];
        NSDictionary *dict = @{@"peripheral":peripheral,@"locolName":locolName,@"peripheralName":peripheralName,@"advertisementData":advertisementData,@"RSSI":RSSI};
         [self.peripherals addObject:dict];
           
        return;
    }
    
    if (self.peripherals.count == 0)//无数据
    {

            NSDictionary *dict = @{@"peripheral":peripheral,@"locolName":locolName,@"peripheralName":peripheralName,@"advertisementData":advertisementData,@"RSSI":RSSI};
            _currentPeripheral = dict;
           
        
        
            //将已连接外设,置为当前外设
            if(peripheral.state == CBPeripheralStateConnected)
            {
                [self.peripherals removeObject:dict];
            
            }
            
        

    }
    else//有数据
    {
        BOOL isExist = NO;
        for (int i = 0; i < self.peripherals.count; i++)
        {
            NSDictionary *dict = [self.peripherals objectAtIndex:i];
            CBPeripheral *per = dict[@"peripheral"];
            if ([per.identifier.UUIDString isEqualToString:peripheral.identifier.UUIDString])//扫描到的外设已有,替换
            {
                isExist = YES;
                NSDictionary *dict = @{@"peripheral":peripheral,@"locolName":locolName,@"peripheralName":peripheralName,@"advertisementData":advertisementData,@"RSSI":RSSI};
                [self.peripherals replaceObjectAtIndex:i withObject:dict];
            }
            
            //去除已连接的外设(判断是否是已连接的外设)
            if (self.currentPeripheral)
            {
                CBPeripheral *currentPer = self.currentPeripheral[@"peripheral"];
                if ([per.identifier.UUIDString isEqualToString:currentPer.identifier.UUIDString]) {
                    
                    [self.peripherals removeObjectAtIndex:i];
                }
            }
            
            
        }
        
        if (!isExist)//(新扫描到的外设添加)
        {



                NSDictionary *dict = @{@"peripheral":peripheral,@"locolName":locolName,@"peripheralName":peripheralName,@"advertisementData":advertisementData,@"RSSI":RSSI};
                [self.peripherals addObject:dict];
                
            
        }
        
        //将已连接外设,置为当前外设
        if(peripheral.state == CBPeripheralStateConnected)
        {
            
            NSDictionary *dict = @{@"peripheral":peripheral,@"locolName":locolName,@"peripheralName":peripheralName,@"advertisementData":advertisementData,@"RSSI":RSSI};
            [self.peripherals removeObject:dict];
            self.currentPeripheral = dict;
            
        }
        
        
    }
    
    if (self.didRefreshPeripherals) {
        self.didRefreshPeripherals();
    }
   

    
}

//第四步:连接蓝牙设备
- (void)connectPeripheral:(CBPeripheral *)peripheral
{
    [self.centerManager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
    /*
     CBConnectPeripheralOptionNotifyOnDisconnectionKey
     在程序被挂起时,断开连接显示Alert提醒框
     */
    // 设置外设的代理是为了后面查询外设的服务和外设的特性,以及特性中的数据。
    [peripheral setDelegate:self];
}

/*第五步:连接成功后,调用扫描蓝牙外设服务的代理
 [peripheral discoverServices:nil];
 */
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    //
    
    
    
    // 连接外设成功后关闭扫描
    [self.centerManager stopScan];
    [peripheral discoverServices:nil];
 
     _currentPeripheral =   self.peripherals.firstObject;
    [self.peripherals removeAllObjects];
         
     
    if (self.didConnectPeripheral) {
           self.didConnectPeripheral();
    }
   
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error//连接失败代理
{
    NSLog(@"didFailToConnectPeripheral====%@",error);
    if (self.didFailToConnectPeripheral) {
        self.currentPeripheral = nil;
           self.didFailToConnectPeripheral();
       }
   
}
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error//收到连接状态断开 代理
{
    
    NSLog(@"已断开连接");
    if (self.didDisconnectPeripheral) {
        self.currentPeripheral = nil;
           self.didDisconnectPeripheral();
       }
}
#pragma mark  ======   CBPeripheralDelegate  =====

//配对成功后走
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    NSString *UUID = [peripheral.identifier UUIDString];
    NSLog(@"didDiscoverServices:%@",UUID);
    
    if (error)
    {
        if (self.didDiscoverServicesErr) {
            self.didDiscoverServicesErr(error);
        }
     
        return;
    }
    
    CBUUID *cbUUID = [CBUUID UUIDWithString:UUID];
    NSLog(@"cbUUID:%@",cbUUID);
    
    for (CBService *service in peripheral.services)
    {
        NSLog(@"---service:%@",service.UUID);
        //可以过滤 to do
        //第六步:扫描到外设服务后,可以获取外设的服务特性 对外设的CBUUID进行所需的处理
       // if ([service.UUID isEqual:@"Device Information"]) {
             [peripheral discoverCharacteristics:nil forService:service];
        //}
        
       
     }
    
}
//发现特征回调
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    for (CBCharacteristic *characteristic in service.characteristics) {
          NSLog(@"发现特征:%@",characteristic);
   
             //订阅
           [peripheral setNotifyValue:YES forCharacteristic:characteristic];
      
      


        
    }
}
//蓝牙交互
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    
   // characteristic.value
    if (self.didReceiveMSG) {
     } 
}

@end

附 查询方法

//第二步:扫描蓝牙外设
- (void)scan:(id)sender
{
    if (_timer)
    {
        [self stopTimer];
    }
    _timeNum = 30;
    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerCount:) userInfo:nil repeats:YES];
    [_timer fire];
    
    [self startScanPeripheral];
}


- (void)startScanPeripheral
{
    if ([BluetoothCenter sharedCenter].centerManager.state != CBManagerStatePoweredOn)
    {
        [ToolBox noticeContent:@"请检查蓝牙是否打开" andShowView:self.view andyOffset:NoticeHeight];
        if ([_tableView.mj_header isRefreshing])
            [_tableView.mj_header endRefreshing];
        return;
    }
    
    #warning  当设置serviceUUIDs参数时,只返回指定的服务(官方推荐做法)
    
    //扫描蓝牙设备
    [[BluetoothCenter sharedCenter].centerManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(NO)}];
    //key值是NSNumber,默认值为NO表示不会重复扫描已经发现的设备,如需要不断获取最新的信号强度RSSI所以一般设为YES了
    
}

- (void)stopScanPeripheral
{

    if ([[BluetoothCenter sharedCenter].centerManager isScanning])
    {
        [[BluetoothCenter sharedCenter].centerManager stopScan];
//        [ToolBox noticeContent:@"扫描结束" andShowView:self.view andyOffset:NoticeHeight];
    }

}

你可能感兴趣的:(oc)