今日分享-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. 相關問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章