今日分享-ios蓝牙

最近新接手智能硬件的项目,要用到ios蓝牙,接下来把最近收集的资料和查到的相关信息分享给大家,划分为一下几个方面

1. ios蓝牙库的基本介绍-CoreBluetooth
2. CoreBluetooth使用详解
3. 相关问题


1. ios蓝牙库的基本介绍-CoreBluetooth
首先熟悉相关名词:Central(中心设备)、Peripheral(外围设备)、advertising(广告)、Services(服务)、Characteristic(特征)

Central:自己的设备(蓝牙)

  • CBCentralManager

Peripheral:搜索到的设备

  • CBPeripheral

advertising:扫描到外围设备时,外围设备所携带的相关信息(有字节长度限制,这
些信息一般都是设备的相关信息)

  • (NSDictionary *)advertisementData

Services:外围设备的服务

  • CBService

Characteristic:外围设备的的特征(可以理解为发现相关服务后,服务下的特征)

  • CBCharacteristic

2. CoreBluetooth使用详解

  • .h 导入头文件,设置代理
#import <CoreBluetooth/CoreBluetooth.h>

<CBCentralManagerDelegate,CBPeripheralDelegate>
  • 初始化蓝牙
self.manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
self.manager.delegate = self;
self.BleViewPerArr = [[NSMutableArray alloc]initWithCapacity:1];
  • 开始扫描
-(void)scan{
    //判断状态开始扫瞄周围设备 第一个参数为空则会扫瞄所有的可连接设备  你可以
    //指定一个CBUUID对象 从而只扫瞄注册用指定服务的设备
    //scanForPeripheralsWithServices方法调用完后会调用代理CBCentralManagerDelegate的
    //- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法
    [self.manager scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];
    //记录目前是扫描状态
    _bluetoothState = BluetoothStateScaning;
    //清空所有外设数组
    [self.BleViewPerArr removeAllObjects];
    //如果蓝牙状态未开启,提示开启蓝牙
    if(_bluetoothFailState==BluetoothFailStateByOff)
    {
        NSLog(@"%@",@"检查您的蓝牙是否开启后重试");
    }

}
  • CBCentralManagerDelegate方法-蓝牙状态检测
 - (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (central.state != CBCentralManagerStatePoweredOn) {
        NSLog(@"fail, state is off.");
        switch (central.state) {
            case CBCentralManagerStatePoweredOff:
                NSLog(@"连接失败了\n请您再检查一下您的手机蓝牙是否开启,\n然后再试一次吧");
                _bluetoothFailState = BluetoothFailStateByOff;
                break;
            case CBCentralManagerStateResetting:
                _bluetoothFailState=BluetoothFailStateByTimeout;
                break;
            case CBCentralManagerStateUnsupported:
                NSLog(@"检测到您的手机不支持蓝牙4.0\n所以建立不了连接.建议更换您\n的手机再试试。");
                _bluetoothFailState = BluetoothFailStateByHW;
                break;
            case CBCentralManagerStateUnauthorized:
                NSLog(@"连接失败了\n请您再检查一下您的手机蓝牙是否开启,\n然后再试一次吧");
                _bluetoothFailState = BluetoothFailStateUnauthorized;
                break;
            case CBCentralManagerStateUnknown:
                _bluetoothFailState = BluetoothFailStateUnKnow;
                break;
            default:
                break;
        }
        return;
    }
    _bluetoothFailState = BluetoothFailStateUnExit;
    // ... so start scanning
}
  • CBCentralManagerDelegate方法-发现周围设备
- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI
{
    if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/)
    {
        return;
    }
    NSString *pername=[NSString stringWithFormat:@"%@",peripheral.name];
    //判断是否存在@"你的设备名"
    NSRange range=[pername rangeOfString:@"你的设备名"];
    //如果从搜索到的设备中找到指定设备名,和BleViewPerArr数组没有它的地址
    //加入BleViewPerArr数组
    if(range.location!=NSNotFound&&[_BleViewPerArr containsObject:peripheral]==NO){
        [_BleViewPerArr addObject:peripheral];
    }
    _bluetoothFailState = BluetoothFailStateUnExit;
    _bluetoothState = BluetoothStateScanSuccess;
}

advertisementData即为蓝牙的广播信息,打印信息如下(不同设备携带数据不同,打印查看,或在硬件文档中查看相关key与value)

{
    kCBAdvDataIsConnectable = 1;
    kCBAdvDataLocalName = "brand";
    kCBAdvDataTxPowerLevel = 2;
}
  • 扫描到设备后连接相关设备
//连接设备,调用此方法,peripheral即为存放在数组中的需要连接的设备(根据自己的需要,判断要连接的设备,取出后调用此方芳连接)
    [_manager connectPeripheral:peripheral
                        options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}];
  • CBCentralManagerDelegate方法-连接上该设备
// 获取当前设备
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"%@",peripheral);

    // 设置设备代理
    [peripheral setDelegate:self];
    // 大概获取服务和特征
    [peripheral discoverServices:nil];

    //或许只获取你的设备蓝牙服务的uuid数组,一个或者多个
    //[peripheral discoverServices:@[[CBUUID UUIDWithString:@""],[CBUUID UUIDWithString:@""]]];


    NSLog(@"Peripheral Connected");

    [_manager stopScan];

    NSLog(@"Scanning stopped");

    _bluetoothState=BluetoothStateConnected;

}

注意:连接失败会调用- (void)centralManager:(CBCentralManager )central didFailToConnectPeripheral:(CBPeripheral )peripheral error:(NSError )error*

  • CBPeripheralDelegate方法-获取服务
// 获取当前设备服务services
 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    if (error) {
        NSLog(@"Error discovering services: %@", [error localizedDescription]);
        return;
    }

    NSLog(@"所有的servicesUUID%@",peripheral.services);

    //遍历所有service
    for (CBService *service in peripheral.services)
    {

        NSLog(@"服务%@",service.UUID);

        //找到你需要的servicesuuid
        if ([service.UUID isEqual:[CBUUID UUIDWithString:@"你的设备服务的uuid"]])
        {
            //监听它
            [peripheral discoverCharacteristics:nil forService:service];
        }



    }
    NSLog(@"此时链接的peripheral:%@",peripheral);

}
  • CBCentralManagerDelegate方法-获取特征值 :特征值有几种不同的属性(读,写等,可打印查看)

重点:(获取特征值后,可以订阅这个特征的通知,也可写入信息到设备,这两种操作均会返回信息,实现与蓝牙设备的交互,看下面的内容)

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{

    if (error)
    {
        NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
        return;
    }
    NSLog(@"服务:%@",service.UUID);
    // 特征
    for (CBCharacteristic *characteristic in service.characteristics)
    {
        NSLog(@"%@",characteristic.UUID);
        //发现特征
        //注意:uuid 分为可读,可写,要区别对待!!!

        //为蓝牙设备写入信息
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
        {
            NSLog(@"监听:%@",characteristic);//监听特征
            //保存characteristic特征值对象
            //以后发信息也是用这个uuid
            _characteristic1 = characteristic;
            [discoveredPeripheral writeValue:d1 forCharacteristic:characteristic1 type:CBCharacteristicWriteWithResponse];
        }

        //订阅characteristic特征值的通知
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
        {
//            _characteristic2 = characteristic;
//            [peripheral setNotifyValue:YES forCharacteristic:_characteristic2];
//            NSLog(@"监听:%@",characteristic);//监听特征
        }
    }
}
  • CBCentralManagerDelegate方法-读取返回的信息

(上段代码中writeValue:为设备写入信息、setNotifyValue:订阅_characteristic2的通知都会返回信息,返回的信息会在对应的代代理方法中获取:代码中打印的characteristic.value即为返回值)

 - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{

    if (error)
       {
         NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
           return;
       }
       NSLog(@"收到的数据:%@",characteristic.value);
 }

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
        return;
    }

    NSLog(@"收到的数据:%@",characteristic.value);
}

3. 相关问题

  • 获取蓝牙设备的mac地址
    由于框架中不带获取mac地址的相关api,不能像安卓一样通过调用getadress方法获取,ios通过向蓝牙设备写入信息,返回相关的mac地址。具体操作:硬件工程师把mac地址写入指定的特征,ios端调用writeValue:方法传入硬件工程师指定的数据,通过didupdatevalue方法获取到返回的mac地址

  • 实现手机与蓝牙设备的绑定问题
    实现手机与蓝牙设备的绑定原理同获取mac地址:写入相关的手机信息,蓝牙设备存储了手机信息,didupdatevalue方法返回了成功的信息即实现了绑定

ps:有什么问题,活着不明白的可在评论区留言或发送站内信,看到后定会及时回复,毕竟都是一步一步踩坑过来的,后续碰到什么问题,也会及时更新在3. 相关问题

你可能感兴趣的:(OC,ios)