关于蓝牙 4.0 BLE 的一点点总结

蓝牙知识从零开始,摸索了一年多,做出了一堆比较渣的东西,觉得有些知识还是有必要记录一下的


蓝牙4.0(低功耗蓝牙)
首先,官方的蓝牙API有几个比较重要的代理方法得实现:

  • 检测当前蓝牙状态,创建CBCentralManager管理类,遵循其代理时,就会触发以下的监听
//检测当前蓝牙状态
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{ 
      switch (central.state) { 
          case CBCentralManagerStatePoweredOn: {
               NSLog(@"Bluetooth is currently powered on."); 
          } 
              break; 
          case CBCentralManagerStatePoweredOff: { 
              NSLog(@"Bluetooth is currently powered off."); 
          } 
              break; 
          case CBCentralManagerStateUnauthorized: {
             NSLog(@"The application is not authorized to use the Bluetooth Low Energy Central/Client role."); 
          } 
              break; 
          case CBCentralManagerStateUnsupported: { 
              NSLog(@"The platform doesn't support the Bluetooth Low Energy Central/Client role."); 
          }
              break; 
          case CBCentralManagerStateResetting: { 
              NSLog(@"The connection with the system service was momentarily lost, update imminent."); 
          }
              break; 
          case CBCentralManagerStateUnknown: { 
              NSLog(@"State unknown, update imminent.");
         }
             break; 
        default: 
            break; 
    }
}
  • 发现蓝牙设备,一旦有CBPeripheral被搜寻到,这个代理方法被调用
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{ 
    //在这里可以获取到发现的设备的信息,例如名字和标识等;也可以通知业务那边,已经发现了符合的设备 
    NSLog(@"发现蓝牙:[名字:%@](标识:%@)",peripheral.name,peripheral.identifier); 
    **需要注意的是,发现的peripheral.identifier是NSUUID类型,需要做处理来使用或者保存(记住这个标识可以在下一次发现时自动;连接)** 
    //连接发现的蓝牙设备 self.peripheral = peripheral; 
    [self.BLEManager connectPeripheral:self.peripheral options:nil];
}
  • 连接上蓝牙,下面的connect回调会告诉我们连接的结果
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
     //一定要设置代理,否则下面的回调接收不到
     [self.peripheral setDelegate:self]; 
    //让peripheral发现自己的服务
     [self.peripheral discoverServices:@[[CBUUID UUIDWithString:ServiceUUID]]];//这里可以指定需要发现的服务,也可以为nil,如果为空就是发现所有的
}
  • 断开蓝牙,下面的didDisconnect回调会告诉我们断开的结果
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ 
    NSLog(@"!!!!!!!!!!蓝牙断开!!!!!!!!"); 
    //在这里做蓝牙断开的处理
}
  • 蓝牙连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ 
    NSLog(@"didFailToConnectPeripheral【%@】",error);
}
  • 发现设备的服务,连上蓝牙后,发现设备的服务会回调到下面这个方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ 
    if (error) { 
        NSLog(@"%s,error=%@",__PRETTY_FUNCTION__,error); 
    } else { 
         for (CBService *service in peripheral.services) { 
            NSLog(@"发现UUID:[%@]",service.UUID); 
            if ([service.UUID isEqual:[CBUUID UUIDWithString:ServiceUUID]]) { 
                //读取特征,筛选到要使用的服务,去发现特征,每个服务一般都有多个特征,它们的值不一样,用途也不一样,这个看设备的指定 
                [self.peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:Characteristic1UUID]] forService:service]; 
            }
         }
     }
}
  • 发现服务中的特征,发现设备服务中的特征后会回调到下面这个方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{ 
    //这里边就可以对特征做一些操作了,例如读设备的数据或者是向设备写入数据,发送指令 
    for (CBCharacteristic *characteristic in service.characteristics) {
         if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:Characteristic1UUID]]) { 
            **特别重要:特征分为两种,一种是设置为通知,有更改,自动更新,一种是要订阅的,value需要自己提取** 
            self.characteristic = characteristic; [self.peripheral setNotifyValue:YES forCharacteristic:self.characteristic]; //[self.peripheral readValueForCharacteristic:self.characteristic]; [self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse]; 
         }
    }
}
  • 接收特征返回的数据,向特征获取数据或者是写入命令,设备底层接收到了,会回调回来(注:并不是所有指令都会有数据返回,这个要看蓝牙底层的实现)
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    //这里能拿到需要的东西
    NSData *data = [characteristic value];
}
  • 更新特征的通知状态(注:必须在这边设置读取特征的值,否则特征值更新不会调用返回值的方法)
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ if (error) { 
    NSLog(@"%s,%@",__PRETTY_FUNCTION__,error); }  
    //已经发送通知
     if (characteristic.isNotifying) { 
        //NSLog(@"Notification began on %@",characteristic);       
        [peripheral readValueForCharacteristic:characteristic]; 
    } else { 

    }
}

以上只是个人在蓝牙4.0开发中的一点点见解,不喜勿喷,写得不是很好,可能有错误或者漏洞,恳请大神斧正。可能还有一些开发过程中遇到的问题没有写上,如有需要交流的童鞋可以留言给本人,共同学习进步。

你可能感兴趣的:(关于蓝牙 4.0 BLE 的一点点总结)