iOS蓝牙开发

最近做了一个蓝牙的app,所以就来梳理了一下自己的蓝牙开发步骤及方式,如有不对,欢迎指出。


第一步

导入CoreBluetooth.framework库

Snip20160618_11.png

*第二步 *

在项目中合适的地方导入头文件
    import <CoreBluetooth/CoreBluetooth.h>
并遵循两个代理
    <CBCentralManagerDelegate,CBPeripheralDelegate>

第三步

初始化CBCentralManager对象
    //(PS:设为nil表示在主线程中执行)        
    manager = [CBCentralManager alloc] initWithDelegate:self queue:nil];

第四步

执行代理方法,此方法在设置完代理后就会执行
-(void)centralManagerDidUpdateState:(CBCentralManager *)central {
    //判断当前蓝牙状态
   switch (central.state) {
   case CBCentralManagerStateUnknown:
       DWLog(@"未知状态");
       break;
   case CBCentralManagerStateUnsupported:
       DWLog(@"模拟器不支持蓝牙调试");
       break;
   case CBCentralManagerStateUnauthorized:
       break;
  case CBCentralManagerStatePoweredOff:
    DWLog(@"蓝牙处于关闭状态");
       break;
   case CBCentralManagerStateResetting:
       break;
   case CBCentralManagerStatePoweredOn:
       DWLog(@"蓝牙已开启");
       //NO表示不会重复搜索以搜索到到设备
       NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
       //当得知蓝牙为开启状态时,直接搜索周围的蓝牙设备
       //开始搜索蓝牙
       [manager scanForPeripheralsWithServices:nil options:options];
         break;
      }
 }

第五步

搜索到蓝牙会调用此方法,可以在此方法里设置搜索过滤规则
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
           //此处设置需要的过滤规则  
          if ([peripheral.name isEqualToString:@"dwang"]) {
                 //将符合要求的设备进行数据持久化,以便下面连接的时候使用
                 self.activePeripheral = peripheral;
           DWLog(@"peripheral.name===%@",peripheral.name);
    }
}

第六步

连接蓝牙
[manager connectPeripheral:self.activePeripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];

连接成功的回调
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
        //连接成功后,设置设备的代理
       peripheral.delegate = self;
       //查找服务
       [peripheral discoverServices:nil];
}

连接失败的回调
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
DWLog(@"连接失败%@",error);
}

第七步

扫描外设中的服务值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error  {
if ([peripheral isEqual:self.activePeripheral]) {
    for (CBService *services in peripheral.services) {
       if ([[services UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的服务UUID"]]) {
           读服务对象 = services;
           [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"接收数据的特征值UUID"],[CBUUID UUIDWithString:@"发送数据的特征值UUID"]] forService:读服务对象];
       }  else if ([[services UUID] isEqual:[CBUUID UUIDWithString:@"发送数据的服务UUID"]])  {
           写服务对象 = services;
           [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:@"接收数据的特征值UUID"],[CBUUID UUIDWithString:@"发送数据的特征值UUID"]] forService:写服务对象];
         }         
      }
   }
}

获取外设中的特征值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error {
if ([peripheral isEqual:self.activePeripheral]){
   // 新建特征值数组
    NSArray *characteristics = [service characteristics];
   DWLog(@"characteristics=%@",characteristics);
   CBCharacteristic *characteristic;
   if ([[service UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的服务UUID"]])  {
       for (characteristic in characteristics)  {
               DWLog(@"发现特值UUID: %@\n", [characteristic UUID].data);
           if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:@"发送数据的特征值UUID"]])  {
              写特征值对象 = characteristic;
           } else if ([[characteristic UUID] isEqual:[CBUUID UUIDWithString:@"接收数据的特征值UUID"]])  {
              读特征值对象 = characteristic;
                 //订阅特征值通知
               [peripheral setNotifyValue:YES forCharacteristic:characteristic];
           }
       }
   }
}
                DWLog(@"%s\n\
                  连接%@设备成功\n\
                  Services==%lu\n\
                  发现服务UUID:\n\
                  service.UUID.data==%@\n\
                  service.UUID==%@\n\
                  characteristic==%@\n\
                  identifier==%@\n\
                  name==%@\n\
                  state==%ld,",
                  __func__,
                  peripheral.name,
                  peripheral.services.count,
                  service.UUID.data,
                  service.UUID,
                  service.characteristics,
                  service.peripheral.identifier,
                  service.peripheral.name,
                  (long)service.peripheral.state);
}

订阅的特征值发生改变会调用此方法
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
            DWLog(@"%@,----%@",[characteristic UUID],[characteristic value]);
}

只要蓝牙设备更新特征值就会调用此方法,此方法一般是只要连接上蓝牙设备就会一直调用
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
           DWLog(@"%@---uuid====%@---value===%@",peripheral.name,[characteristic UUID],characteristic.value);
}

第八步

发送数据
//一般数据发送给蓝牙的数据都是字节数据,这就需要看你们之间的协议了,在这里我就直接用字节举例
Byte byte[] = {
     1, 2, 3, 4, 5,
      6, 7, 8, 9, 10,
      11, 12, 13, 14, 15,
      16, 17, 18, 19, 20     
 };
////蓝牙一次最多只能接收20字节的数据,超过20字节就需要分段发送,否则无法发送成功。也许会在发送完成后的回调方法中出现没有写入权限的错误
NSData *data = [NSData dataWithBytes:byte length:20];
//type:需要知道蓝牙外设的类型,否则无法成功发送数据,并且如果使用CBCharacteristicWriteWithoutResponse就不会走发送数据的回调
[self.activePeripheral writeValue:data forCharacteristic:写特征值对象 type:CBCharacteristicWriteWithoutResponse];

数据发送之后的回调
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
     DWLog(@"完成数据写入===%@ ---- characteristic.UUID==%@", characteristic.value, characteristic.UUID);
          DWLog(@"数据发送失败===error: %@", error);
}

这里有一个我写的Demo:如需使用只需要改一些必要参数就可以了

OK

圆满结束

欢迎各位加我QQ:739814184一同讨论,一同进步

也可以扫描二维码加我微信

4DBF63071DCD3695DD0E205DDC04132E.png

推荐阅读更多精彩内容