IOS 上蓝牙协议只支持4.0以上

如果需要调用蓝牙协议需要添加<CoreBluetooth/CoreBluetooth.h>框架

 

1.中心管理者

IOS中的蓝牙分为: 中心管理设计模式和外设管理设计模式

/**
 *  中心管理者
 */
@property(nonatomic,strong) CBCentralManager * BleCenter ;
 
把中心管理者设置成属性后,写一个中心管理者的懒加载
 
-(CBCentralManager *)BleCenter
{
 
    if (!_BleCenter) {
        _BleCenter= [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
    }
    return _BleCenter;
}

这里注意在初始化重新管理者的时候必须遵守协议CBCentralManagerDelegate,并且需要在主线程中实现。

 

2.扫描外设

  • 扫描的方法防治cMgr成功打开的代理方法中
  • 只有设备成功打开,才能开始扫描,否则会报错

 

初始化中心管理者完成后会触发一个方法是必须实现的

-(void)centralManagerDidUpdateState:(CBCentralManager *)central

CBCentralManagerStateUnknown:

(@"未知情况")     

CBCentralManagerStateResetting:

(@"重置")

CBCentralManagerStateUnsupported:

(@"无支持")

CBCentralManagerStatePoweredOff:

(@"关闭")

CBCentralManagerStateUnauthorized:

(@"未经授权")

CBCentralManagerStatePoweredOn:

//扫描周边设备搜索成功后会调用找到外设的代理方法

[self.BleCenter scanForPeripheralsWithServices:nil options:nil];

(@"开启")

 

 

 3.接下来可以连接设备
 如果你没有设备,可以下载一个app叫lightbule的app去模拟一个设备
 判断设备号是否扫描到

 

@param central 中心管理者
 @param peripheral 外设
 @param advertisementData 外设携带的数据
 @param RSSI 外设发出的信号强度
//找到外设代理方法
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral
*)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI

 

在这个方法中我们需要对连接到的外设进行筛选,根据以下两点来筛选。

/*
  
  peripheral = <CBPeripheral: 0x166668f0 identifier =
C69010E7-EB75-E078-FFB4-421B4B951341, Name = "OBand-75", state =
disconnected>, advertisementData = {
  
  kCBAdvDataChannel = 38;
  
  kCBAdvDataIsConnectable = 1;
  
  kCBAdvDataLocalName = OBand;
  
  kCBAdvDataManufacturerData = <4c69616e 0e060678 a5043853 75>;
  
  kCBAdvDataServiceUUIDs =     (
  
  FEE7
  
  );
  
  kCBAdvDataTxPowerLevel = 0;
  
  }, RSSI = -55
     根据打印结果,我们可以得到运动手环它的名字叫 OBand-75
 
   
  
  */
 
//需要对连接到的外设进行筛选,1.根据信号强度 2.通过设备名(设备字符串的前缀)
    if ([peripheral.name hasPrefix:@"截取设备字符串的前缀"] && (RSSI.integerValue
>40)) {
  
     
        //标记外设,让他的生命周期
= vc
        self.peripheral =
peripheral;
        //设备连接
        [self.BleCenter connectPeripheral:self.peripheral options:nil];
 
  }

4.1 获取外设的services

  • 首先设置外设的代理,并搜寻services
  • 然后在代理方法peripheral:didDiscoverServices:中遍历services

 

//中心管理者连接外设成功
-(void)centralManager:(CBCentralManager *)central
 didConnectPeripheral:(CBPeripheral
*)peripheral
{
    NSLog(@"%s, line = %d,%@连接成功",__FUNCTION__,__LINE__,peripheral.name);
  
 
    //设置代理
    self.peripheral.delegate = self;
    //发现服务,传nil代表不过滤
    //这里会触发 发现外设的服务器后调用的方法
    [self.peripheral discoverServices:nil];
  
 
}
 
//丢失连接
-(void)centralManager:(CBCentralManager *)central
didDisconnectPeripheral:(CBPeripheral *)peripheral
               
error:(NSError *)error
{
    NSLog(@"%s, line = %d,%@丢失连接",__FUNCTION__,__LINE__,peripheral.name);
}
 
//外设连接失败
-(void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral
*)peripheral
               
error:(NSError *)error
{
    NSLog(@"%s, line = %d,%@外设连接失败",__FUNCTION__,__LINE__,peripheral.name);
}
 
//发现外设的服务后调用
-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error
{
    if (error) {
        NSLog(@"%s, line = %d, erro = %@", __FUNCTION__,__LINE__,error.localizedDescription);
 
  }
    for (CBService *service in peripheral.services) {
        //发现服务后,让设备在发现服务内部的特征们
        [peripheral discoverIncludedServices:nil forService:service];
  
     
 
  }
  
 
}

 

4.2 获取外设的characteris,获取Characteristics的值,获取Characteristics的Descriptor以及Descriptor的值

//发现外设服务里的特征的时候调用的代理方法
-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
            error:(NSError *)error
{
    NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
    for (CBCharacteristic *cha in service.characteristics) {
        NSLog(@"%s, line = %d,char = %@",__FUNCTION__,__LINE__,cha);
        //获取特征对应的描述
        [peripheral discoverDescriptorsForCharacteristic:cha];
        //获取特征的值
        [peripheral readValueForCharacteristic:cha];
  
     
  
     
 
  }
}
 
//更新特征对应的值,时候调用
-(void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)
characteristic error:(NSError *)error
{
    NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
    for (CBDescriptor *descriptor in characteristic.descriptors) {
        //它会触发 发现外设的特征描述数组
        [peripheral readValueForDescriptor:descriptor];
 
  }
}
 
//更新特征和对应的描述,时候调用
-(void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForDescriptor:(CBDescriptor
*)descriptor
            error:(NSError *)error
{
    //当描述的值更新的时候,直接调用此方法
    [peripheral readValueForDescriptor:descriptor];
  
 
    NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
}
 
// 发现外设的特征的描述数组
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic
*)characteristic
             error:(nullable NSError *)error
{
    NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
    //
在此处读取描述即可
    for (CBDescriptor *descriptor in characteristic.descriptors) {
  
     
        [peripheral readValueForDescriptor:descriptor];
 
  }
}

5.写数据到特征中

/**
 *  写入数据
 */
// 需要注意的是特征的属性是否支持写数据
-(void)LXC_peripheral:(CBPeripheral *)peripheral
        didWriteData:(NSData *)data
   forCharacteristic:(nonnull CBCharacteristic
*)characteristic
{
    NSLog(@"%s, line = %d
,characteristic.properties = %lu",__FUNCTION__,__LINE__,(unsigned long)characteristic.properties);
//此时由于枚举属性是NS_OPTIONS,所以一个枚举可能对应多个类型,所以判断不能用 = ,应该用 &
    if (characteristic.properties &CBCharacteristicPropertyWriteWithoutResponse) {
        //写入值
        [peripheral writeValue:data //写入数据
             forCharacteristic:characteristic //写给哪个
                 
        type:CBCharacteristicWriteWithResponse]; //通过此响应记录是否成功写入
  
     
 
  }
}

6.订阅特征的通知

/**
 *  外设特征订阅通知
 */
-(void)LXC_peripheral:(CBPeripheral *)peripheral
regNotifyWithCharacteristic:(nonnull CBCharacteristic
*)characteristic
 
{
  
 
     // 设置通知, 数据会进入
peripheral:didUpdateValueForCharacteristic:error:方法
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
  
 
}
 
-(void)LXC_peripheral:(CBPeripheral *)peripheral
CancleRegNotifyWithCharacteristic:(nonnull CBCharacteristic
*)characteristic
 
{   //外设为特征取消通知
    [peripheral setNotifyValue:NO forCharacteristic:characteristic];
 
 
  
 
}
7.断开连接
/**
 *  断开连接
 */
-(void)LXC_dismissConentedWithperipheral:(CBPeripheral
*)peripheral
{
    //停止扫描
    [self.BleCenter stopScan];
    //断开连接
    [self.BleCenter cancelPeripheralConnection:peripheral];
}