iOS蓝牙开发

作者: 75afc06dcc73 | 来源:发表于2016-06-18 18:43 被阅读811次

    最近做了一个蓝牙的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

    相关文章

      网友评论

      • 尛焱:scanForPeripheralsWithServices:方法的第一个参数就可以设置过滤规则了,需要下位机广播里加入ServiceUUID
        75afc06dcc73:@尛唁 手机连接外设 我是做健身器材的
        尛焱:我公司做手环的,下位机设置的;你都是手机做中心外设的?
        75afc06dcc73:@尛唁 但是我在使用时发现,在scan中添加过滤规则有时会无法搜索到设备,好像是和发送的报文有关,我到百度查过。所以我没写在那里添加过滤规则。
        不过还是谢谢,提出意见,以后我会写的详细一点的
      • 6991a5a482e5:哇,同在青岛,不同的是我是菜鸟。大神带我飞~
        75afc06dcc73:@dxykevin 我也是鸟

      本文标题:iOS蓝牙开发

      本文链接:https://www.haomeiwen.com/subject/oiovdttx.html