iOS开发收藏文章iOS学习开发iOS Developer

浅谈iOS中的蓝牙技术(二) -- CoreBluetooth

2016-04-21  本文已影响740人  相关函数

在上篇文章中我们提到了 iOS 开发中,使用GameKit 框架实现相同网络的 iOS 设备之间传输数据.但是 GameKit 框架在 iOS7 之后就过时了,那么本文将介绍另一种关于蓝牙的框架 CoreBluetooth.

CoreBluetooth

简介
CoreBluetooth.h

上图是CoreBluetooth 的头文件,在这个框架中最核心的两个东西就是 Central (中心)和 Peripheral(外设).

图片来自网络,如有侵权,请联系
CoreBluetooth 中的对象模型

实现通讯

中心管理设计模式

导入 CoreBluetooth 头文件,创建中心管理者属性和外设属性,并遵守中心管理者和外设的协议.

First
- (CBCentralManager *)getCManager{
    if (!_cManager) {
        _cManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
    }
    return _cManager;
}
// 该方法用于告诉Central Manager,要开始寻找一个指定的服务了.不能在state非ON的情况下对我们的中心管理者进行操作,scanForPeripheralsWithServices方法中 sercices为空则会扫描所有的设备.
 - (void)centralManagerDidUpdateState:(CBCentralManager *)central{

    switch (central.state) {
        case CBCentralManagerStateUnknown:
            NSLog(@"中心管理器状态未知");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@"中心管理器状态重置");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"中心管理器状态不被支持");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"中心管理器状态未被授权");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@"中心管理器状态电源关闭");
            break;
        case CBCentralManagerStatePoweredOn:
        {
            NSLog(@"中心管理器状态电源开启");
            // 在中心管理者成功开启后开始搜索外设
            
            [self.cManager scanForPeripheralsWithServices:nil options:nil]; 
            // 搜索成功之后,会调用我们找到外设的代理方法 sercices为空则会扫描所有的设备
            // - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI; //找到外设
            
        }
            break;
        default:
            break;
    }
}
/*
 *  @param central              中央管理器提供此更新
 *  @param peripheral           一个外设对象
 *  @param advertisementData    一个包含任何广播和扫描响应数据的字典。
 *  @param RSSI                 RSSI(Received Signal Strength Indicator)是接收信号的强度指示
 *
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
    
    if ([peripheral.name hasPrefix:@"XXX"] && (ABS(RSSI.integerValue) > 35)) {
        // 标记我们的外设,延长他的生命周期
        self.peripheral = peripheral;
        // 进行连接
        [self.cManager connectPeripheral:self.peripheral options:nil];
    }

}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    NSLog(@"%@连接成功",peripheral.name);
    // 获取外设的服务
    // 设置外设的代理
    self.peripheral.delegate = self;
    // 外设发现服务,传nil代表不过滤
    // 这里会触发外设的代理方法 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
    [self.peripheral discoverServices:nil];
}

// 外设连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"%@连接失败",peripheral.name);
}

// 丢失连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"%@断开连接",peripheral.name);
}
// 发现外设的服务后调用的方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // 判断没有失败
    if (error) {
        NSLog(@"error:%@",error.localizedDescription);
        return;
    }
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:nil forService:service];
    }
}

// 发现服务后,让设备再发现服务内部的特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // 遍历特征
    for (CBCharacteristic *characteristic in service.characteristics) {
        // 获取特征对应的描述
        [peripheral discoverDescriptorsForCharacteristic:characteristic];
        // 获取特征的值
        [peripheral readValueForCharacteristic:characteristic];
    }
}
// 更新特征的描述的值的时候会调用
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error
{
    [peripheral readValueForDescriptor:descriptor];
}

// 更新特征的value的时候会调用
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    for (CBDescriptor *descriptor in characteristic.descriptors) {
        [peripheral readValueForDescriptor:descriptor];
    }
}
NS_OPTIONS类型的特征属性
- (void)peripheral:(CBPeripheral *)peripheral didWriteData:(NSData *)data forCharacteristic:(nonnull CBCharacteristic *)characteristic
{
    
    // 
    if (characteristic.properties & CBCharacteristicPropertyWrite) {
    // 下面方法中参数的意义依次是:写入的数据 写给哪个特征 通过此响应记录是否成功写入
        [peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
    }
}
- (void)peripheral:(CBPeripheral *)peripheral regNotifyWithCharacteristic:(nonnull CBCharacteristic *)characteristic
{
    // 外设为特征订阅通知
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
- (void)peripheral:(CBPeripheral *)peripheral CancleRegNotifyWithCharacteristic:(nonnull CBCharacteristic *)characteristic
{
    // 外设取消订阅通知
    [peripheral setNotifyValue:NO forCharacteristic:characteristic];
}
- (void)dismissConentedWithPeripheral:(CBPeripheral *)peripheral
{
    // 停止扫描
    [self.cManager stopScan];
    // 断开连接
    [self.cManager cancelPeripheralConnection:peripheral];
}

END

外设管理设计模式,跟中心管理设计模式类似,就不赘述,需要遵守 外设管理器协议 和中心协议,设置代理,遵守其中的方法.代码地址:https://github.com/coderqiao/CoreBluetooth.

上一篇 下一篇

猜你喜欢

热点阅读