美文网首页
iOS蓝牙开发流程

iOS蓝牙开发流程

作者: 夕儿77 | 来源:发表于2019-06-04 16:14 被阅读0次

    借鉴

    配置

    • 引入头文件 #import <CoreBluetooth/CoreBluetooth.h>
    • 协议 <CBCentralManagerDelegate,CBPeripheralDelegate>

    创建一个CBCentralManager实例来进行蓝牙管理

    /*
    * 初始化 将self设置为代理 用于接收各种 central 事件
    * 将queue设置为nil,则表示直接在主线程中运行
    * 可以自己设置线程 
    */ 
    CBCentralManager *centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    

    获取蓝牙状态 可用状态下搜索扫描外围设备

    /*
    * 创建Central管理器时,管理器对象会调用代理对象的centralManagerDidUpdateState:方法。
    * 我们需要实现这个方法来确保本地设备支持BLE
    */
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
        switch (central.state) {
            case CBManagerStateUnknown:
                NSLog(@">>>初始的时候是未知的(刚刚创建的时候)");
                break;
            case CBManagerStateResetting:
                NSLog(@">>>正在重置状态");
                break;
            case CBManagerStateUnsupported:
                NSLog(@">>>设备不支持的状态");
                break;
            case CBManagerStateUnauthorized:
                NSLog(@">>>设备未授权状态");
                break;
            case CBManagerStatePoweredOff:
                NSLog(@">>>设备关闭状态");
                break;
            case CBManagerStatePoweredOn:
            {
                NSLog(@">>>设备开启状态 -- 可用状态");
                [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    
            }
                break;
            default:
                break;
        }
    }
    
    

    查找外设

     /*
      *  @param services 中心要扫描的蓝牙设备类型  每个peripheral的 service 都有唯一标识——UUID
      *  @param options  可选 设置这个 option 会对电池寿命和 app 的性能产生不利影响,所以一定要在必要的时候 
      *  @{CBCentralManagerScanOptionAllowDuplicatesKey : @NO } key值是NSNumber,默认值为NO表示不会重复扫描已经发现的设备,如需要不断获取最新的信号强度RSSI所以一般设为YES 
      *  options:@{CBCentralManagerScanOptionSolicitedServiceUUIDsKey:@[[CBUUID UUIDWithString:[USER_DEFAULT objectForKey:KEY_SELECED_FOB]]]} 想要扫描的服务的UUID,以一个数组的形式存在。也就是说指定这个选项后central便会找指定的服务的UUID。
      */
       [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    

    停止扫描外围设备。

     [self.centralManager stopScan]
    

    发现外设

    /*
    * 找到可用设备,系统会回调(每找到一个都会回调)
    * @param peripheral 找到的外设可以是多个
    * @param advertisementData   外设携带的数据
    * @param RSSI   外设发出的蓝牙信号强度
    */
    - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary*)advertisementData RSSI:(NSNumber *)RSSI
    {
    //显示外设
    }
    

    连接外设

    /*
    * @param peripheral 连接的外设
    * @param options     可选
    * @{CBConnectPeripheralOptionNotifyOnConnectionKey: @YES}  在程序被挂起时,连接成功显示Alert提醒框 
    * @{CBConnectPeripheralOptionNotifyOnDisconnectionKey: @YES} 在程序被挂起时,断开连接显示Alert提醒框
    * @{CBConnectPeripheralOptionNotifyOnNotificationKey: @YES} 在程序被挂起时,显示所有的提醒消息
    */
     [self.centralManager connectPeripheral:peripheral options:nil];
    

    连接外设--失败

    - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    }
    

    连接外设--断开

    - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    }
    

    连接外设--成功

    /*
    * 外设的服务、特征、描述等方法是CBPeripheralDelegate的内容,所以要先设置代理 设置外设的代理
    * 查找外设的服务
    */
    - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
             peripheral.delegate = self;
           /*
            * @param discoverServices 的值是空的时候是不过滤 查找所有的外设服务 
            *  可以自定义 [CBUUID UUIDWithString:@"你要用的服务UUID"]
            */
            [self.peripheral discoverServices:nil];
    }
    

    发现服务回调 查找对应的特征

    /*
    *Core Bluetooth 提供了CBService类来表示 service,
    *找到以后,它们以数组的形式存入了当前 peripheral 的services属性中,
    *你可以在当前回调中遍历这个属性
    */
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
        CBService * __nullable findService = nil;
        // 遍历服务
        for (CBService *service in peripheral.services)
        {
            if ([[service UUID] isEqual:[CBUUID UUIDWithString:@"你要用的服务UUID"]])
            {
                findService = service;
            }
        }
        if (findService)
              /*
               *@param discoverServices 空的时候是搜索全部的特征 或者写入你要用的特征UUID
               *@param forService 你需要的查服务
               */
            [peripheral discoverCharacteristics:NULL forService:findService];
    }
    

    发现特征回调

    /*
    *Core Bluetooth 提供了CBCharacteristic类来表示characteristic。可以通过以下代码来遍历找到的 characteristic
    *
    */
    - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
        for (CBCharacteristic *characteristic in service.characteristics) {
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你要用的特征UUID"]]) {
                self.characteristic = characteristic;
               /*
                * 接收特征的两个方法
                * [peripheral readValueForCharacteristic:characteristic]; read这种方法是需要主动去接收的
                * notify方法订阅,当有数据发送时,可以直接在回调中接收,如果 characteristic 的数据经常变化,那么采用订阅的方式更好
                * setNotifyValue YES 为订阅 为NO来取消订阅
                */
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
             /*
              * 当发现characteristic有descriptor,回调didDiscoverDescriptorsForCharacteristic
              */
            [peripheral discoverDescriptorsForCharacteristic:characteristic];
        }
    }
    

    获取外设发来的数据

    /*
    * 不论是read和notify,获取数据都是从这个方法中读取。
    */
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
        // characteristic.value就是蓝牙给我们的值(我这里是json格式字符串)
        //    NSData *jsonData = [characteristic.value dataUsingEncoding:NSUTF8StringEncoding];
        //    NSDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
        // 将字典传出去就可以使用了
    }
    

    中心读取外设实时数据

    /*
     *标识订阅成功吧,获取蓝牙返回数据还是上边的那个方法
     */
    - (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
        if (characteristic.isNotifying) {
            [peripheral readValueForCharacteristic:characteristic];
        } else {
            NSLog(@"Notification stopped on %@.  Disconnecting", characteristic);
            NSLog(@"%@", characteristic);
            [self.centralManager cancelPeripheralConnection:peripheral];
        }
    }
    

    写入数据

    /*
     * @param data 你想要写入的数据
     * @param Characteristic 你想要写入的数据
     * @param type  
     *CBCharacteristicWriteWithResponse  外围设备的响应来指示写入是否成功
     *CBCharacteristicWriteWithoutResponse 不需要来自外围设备的任何响应来指示写入是否成功
     */
     [self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];
    

    数据写入成功回调

    - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
        NSLog(@"写入成功");
    }
    

    断开连接

    /*
    * 断开连接后回调didDisconnectPeripheral
    * 这个方法是非阻塞的,所以其他正在进行的通讯可能完成也可能因此没完成
    * 因为其他应用可能仍保持跟这个设备的连接,
    * 所以当前的取消连接并不能保证底层就立即断开物理上的连接
    */
     [self.centralManager cancelPeripheralConnection:peripheral];
    

    相关文章

      网友评论

          本文标题:iOS蓝牙开发流程

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