蓝牙学习

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];

}

posted @ 2016-04-22 14:14  偷吃的喵  阅读(524)  评论(0编辑  收藏  举报