iOS蓝牙开发流程

2019-06-04  本文已影响0人  夕儿77

借鉴

配置

创建一个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];
上一篇下一篇

猜你喜欢

热点阅读