• core bluetooth详细介绍


    遵守CBCentralManagerDelegate代理和CBPeripheralDelegate代理

    在使用你的应用去扫描设备之前,先要确定你的蓝牙是否已经打开,所以我们要做一个判断:

    其中f3d9是我连接到iPad mini2的LightBlue app模拟的BLE外围设备,你要换成你设备的UUID。

    centralManagerDidUpdateState是CBCentralManagerDelegate必须实现的方法
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
        if (central.state == CBCentralManagerStatePoweredOn) {
            [self.centralManger scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"f3d9"]] options:nil];
        }
    }
     switch (central.state) {
                case CBCentralManagerStateUnknown:
                    NSLog(@">>>CBCentralManagerStateUnknown");
                    break;
                case CBCentralManagerStateResetting:
                    NSLog(@">>>CBCentralManagerStateResetting");
                    break;
                case CBCentralManagerStateUnsupported:
                    NSLog(@">>>CBCentralManagerStateUnsupported");
                    break;
                case CBCentralManagerStateUnauthorized:
                    NSLog(@">>>CBCentralManagerStateUnauthorized");
                    break;
                case CBCentralManagerStatePoweredOff:
                    NSLog(@">>>CBCentralManagerStatePoweredOff");
                    break;
                case CBCentralManagerStatePoweredOn:
                    NSLog(@">>>CBCentralManagerStatePoweredOn");
                   // 把最上面的代码放到这里
              break; default: break; } }

    中心:

    1.建立中心角色

    顺便设置中心的代理是自己

    CBCentralManager *manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

    或者是:

    manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];

     2.扫描外设

    [manager scanForPeripheralsWithServices:nil options:options];

    3.连接外设

    扫描到4.0的外设后进行连接,下面的方法是确定发现外设,把发现的外设对象存放到数组中

    中心回调方法:发现外设

    前提:定义好了NSMutableArray *dicoveredPeripherals;这个用来保存发现的外设对象

    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
    {
        // 把外设保存起来
        if(![_dicoveredPeripherals containsObject:peripheral])
            [_dicoveredPeripherals addObject:peripheral];
         [manager connectPeripheral:peripheral options:nil];
    NSLog(@"dicoveredPeripherals:%@", _dicoveredPeripherals);

     if ([peripheral.name hasPrefix:@"P"]){
                //找到的设备必须持有它,否则CBCentralManager中也不会保存peripheral,那么CBPeripheralDelegate中的方法也不会被调用!!
                [peripherals addObject:peripheral];
                // 发现设备后就连接,根据外设的名臣连接设备
                [manager connectPeripheral:peripheral options:nil];
            } 
        }
    }

    // 当我们查找到Peripheral端时,我们可以停止查找其它设备,以节省电量

    
    

        //    [_definecentermanager stopScan];

     

    上面的代码可以优化成,连接指定的外设名称

    一个主设备最多能连7个外设,每个外设最多只能给一个主设备连接,连接成功,失败,断开会进入各自的委托

    4.扫描外设的服务和特征

    下面的方法是确定已经连接到外设,然后才去扫描外设的服务和特征;设备下面有服务,服务下面有特征;服务有UUID,特征也有UUID;

    中心回调方法:连接外设成功

    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;//连接外设成功的委托

    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
    {
      // 设置外设的代理是自己    
      [peripheral setDelegate:self];
      // 连接外设成功后,开始扫描服务   [peripheral discoverServices:nil]; }

     中心回调方法:连接外设失败

    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//外设连接失败的委托

    中心回调方法:断开外设连接

    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;//断开外设的委托

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    上面一般回调的是CBCentralManagerDelegate代理方法,一般是CentralManager开头;

    下面开始扫描服务和特征时,回调的是CBPeripheralDelegate代理方法,一般是Peripheral开头;

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    分界线:

    设备连接成功后,就可以扫描设备的服务了,同样是通过委托形式,扫描到结果后会进入委托方法。但是这个委托已经不再是主设备的委托(CBCentralManagerDelegate),而是外设的委托(CBPeripheralDelegate,这个委托包含了主设备与外设交互的许多 回调方法,包括获取services,获取characteristics,获取characteristics的值,获取characteristicsDescriptor,和Descriptor的值,写数据,读rssi,用通知的方式订阅数据等等。

    5.确定发现了服务,调用下面的方法;设备下面有服务,服务下面有特征;服务有UUID,特征也有UUID;

    外设回调方法:

    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
      
    for (CBService *service in peripheral.services){

        if ([service.UUID isEqual:[CBUUID UUIDWithString:@"?"]]){

                NSLog(@"Service found with UUID: %@", service.UUID);

            // 发现服务成功后去扫描该服务的特征
                [peripheral discoverCharacteristics:nil forService:service];break;
            } 
        }
    }

    6.根据服务找到了特征

    针对某个服务确定发现了特征;设备下面有服务,服务下面有特征;服务有UUID,特征也有UUID;

    外设回调方法:

    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
      // 根据服务发现了特征,可以对服务的特征进行遍历,也可以针对某个特征的UUID来进行单独处理,下面提供两种,一种是遍历全部,一种是针对某个
      // 遍历全部
        //获取Characteristic的值,读到数据会进入方法:
    // -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    for (CBCharacteristic *characteristic in service.characteristics){ [peripheral readValueForCharacteristic:characteristic]; } //搜索Characteristic的Descriptors,读到数据会进入方法:
         // -(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
    for (CBCharacteristic *characteristic in service.characteristics){ [peripheral discoverDescriptorsForCharacteristic:characteristic]; }
      // 针对某个特征,通过UUID判断这个特征
        
    for (CBCharacteristic *characteristic in service.characteristics){ if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUIDSTR_ISSC_TRANS_TX]]){ NSLog(@"Discovered read characteristics:%@ for service: %@", characteristic.UUID, service.UUID); _readCharacteristic = characteristic;//保存读的特征
            // 自己设置代理,让代理去执行读特征的方法
    if ([self.delegate respondsToSelector:@selector(DidFoundReadChar:)]){ [self.delegate DidFoundReadChar:characteristic]; break; } } for (CBCharacteristic * characteristic in service.characteristics){ if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:UUIDSTR_ISSC_TRANS_RX]]){ NSLog(@"Discovered write characteristics:%@ for service: %@", characteristic.UUID, service.UUID); _writeCharacteristic = characteristic;//保存写的特征
            // 自己设置代理,让代理去执行读特征的方法
              if ([self.delegate respondsToSelector:@selector(DidFoundWriteChar:)])
                    [self.delegate DidFoundWriteChar:characteristic];
                break;
            }
        }
        // 调用根据外设发现特征的代理方法;
        if ([self.delegate respondsToSelector:@selector(DidFoundCharacteristic:withPeripheral:error:)])
            [self.delegate DidFoundCharacteristic:nil withPeripheral:nil error:nil];
        
    }

    找到服务和特征还有以下回调方法在下面:

    外设回调方法:

    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
        [_recvData appendData:characteristic.value];
        if ([_recvData length] >= 5)//已收到长度{
            unsigned char *buffer = (unsigned char *)[_recvData bytes];
            int nLen = buffer[3]*256 + buffer[4];
            if ([_recvData length] == (nLen+3+2+2)){
                //接收完毕,通知代理做事
                if ([_mainMenuDelegate respondsToSelector:@selector(DidNotifyReadData)])
                    [_mainMenuDelegate DidNotifyReadData];
            }
        } 
    }
    //搜索到Characteristic的Descriptors
        -(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
            //打印出Characteristic和他的Descriptors
            NSLog(@"characteristic uuid:%@",characteristic.UUID);
            for (CBDescriptor *d in characteristic.descriptors) {
                NSLog(@"Descriptor uuid:%@",d.UUID);
            }  
        }
      //获取到Descriptors的值
        -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error{
            //打印出DescriptorsUUID 和value
            //这个descriptor都是对于characteristic的描述,一般都是字符串,所以这里我们转换成字符串去解析
            NSLog(@"characteristic uuid:%@  value:%@",[NSString stringWithFormat:@"%@",descriptor.UUID],descriptor.value);
        }

    现在先做数据交互

    7.和外设做数据交互

    1)写数据:

    -(void)writeChar:(NSData *)data{
        [_testPeripheral writeValue:data forCharacteristic:_writeCharacteristic type:CBCharacteristicWriteWithResponse];
    }
    //写数据
    -(void)writeCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic value:(NSData *)value{
        // 打印出 characteristic 的权限,可以看到有很多种,这是一个NS_OPTIONS,就是可以同时用于好几个值,常见的有read,write,notify,indicate,
      // 知知道这几个基本就够用了,前连个是读写权限,后两个都是通知,两种不同的通知方式。
    // CBCharcteristicProperties是一个枚举值,有很多// 只有 characteristic.properties 有write的权限才可以写 if(characteristic.properties & CBCharacteristicPropertyWrite){ // 最好一个type参数可以为CBCharacteristicWriteWithResponse或type:CBCharacteristicWriteWithResponse,区别是是否会有反馈 [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; }else{ NSLog(@"该字段不可写!"); } }

    2)读数据:注意:数据的读分两种,一种是直接读,一种是订阅;方式的选择通过特征的characteristic.properties来规定;

    订阅的方式是:

    订阅方法1:

    -(void)startSubscribe{
        [_testPeripheral setNotifyValue:YES forCharacteristic:_readCharacteristic];
    }

    订阅方法2:

     //设置通知
     -(void)notifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic{
        //设置通知,数据通知会进入:didUpdateValueForCharacteristic方法
        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    }
    //取消通知
    -(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic{
        [peripheral setNotifyValue:NO forCharacteristic:characteristic];
    }

    8.主动断开设备

    方法1:

    -(void)disConnect{
        if (_testPeripheral != nil){
            NSLog(@"disConnect start");
            [manager cancelPeripheralConnection:_testPeripheral];
        } 
    }

     方法2:

      //停止扫描并断开连接
    -(void)disconnectPeripheral:(CBCentralManager *)centralManager peripheral:(CBPeripheral *)peripheral{
        //停止扫描
        [centralManager stopScan];
        //断开连接
        [centralManager cancelPeripheralConnection:peripheral];
    }
  • 相关阅读:
    contes配置nginx教程
    jquery 图片放大镜,草稿版
    VUE学习第四次
    VUE学习 第三次
    ryu
    ovs & ryu & mininet
    centos安装mininet 和卸载
    端口镜像
    数据中心网络监控小结
    5、Kafka生产过程分析
  • 原文地址:https://www.cnblogs.com/williamliuwen/p/5397607.html
Copyright © 2020-2023  润新知