iOS藍牙(BLE4.0低功耗)詳細滲透講解

iOS 藍牙4.0開發使用

嗨大家好,我是iOS開發一枚大帥比,過去的幾年項目涉及到藍牙比較多,抽空之余,把使用的小知識點歸納起來,一是方便自己對知識做很好的總結和復習,二是希望能幫助到瑯琊開發的朋友們。

一、簡介(什么是BLE4.0?哪里使用它?)

現在的互聯網時代,智能硬件設備越來越多樣化,這些設備中,有多是通過手機來控制硬件設備,來達到控制的效果,這中間少不了要使用到藍牙功能,通過藍牙來通信來控制設備。也就是我們說的“設備中心和外設的故事”。

藍牙版本介紹:

每個人對于藍牙都不陌生,近距離數據傳輸,方便;可是當你的業務需求需要你第一次接觸藍牙開發的時候,卻會發現你對它并不了解;首先,藍牙發展至今經歷了8個版本的更新。1.1、1.2、2.0、2.1、3.0、4.0、4.1、4.2。那么在1.x~3.0之間的我們稱之為傳統藍牙,4.x開始的藍牙我們稱之為低功耗藍牙也就是藍牙ble,當然4.x版本的藍牙也是向下兼容的。android手機必須系統版本4.3及以上才支持BLE API。低功耗藍牙較傳統藍牙,傳輸速度更快,覆蓋范圍更廣,安全性更高,延遲更短,耗電極低等等優點。(現在的穿戴設備都是使用BLE藍牙技術的)

傳統藍牙與低功耗藍牙通信方式也有所不同,傳統的一般通過socket方式,而低功耗藍牙是通過Gatt協議來實現。

本文章目的便是介紹BLE 4.0的使用以及相關問題的解決,本文采用簡要模式介紹BLE4.0的核心類的使用以及藍牙開發的簡介,如需了解藍牙知識的詳細知識點,百度可搜索其他大神的文章進行學習,下文通用BLE代為藍牙4.0。

二、BLE的核心模式

BLE的兩種模式分為CBCentralMannager 中心模式 和CBPeripheralManager 外設模式,在這里主要和大家分享CBCentralMannager 中心模式的開發和使用。

CBCentralMannager 中心模式

以手機(app)作為設備中心,連接其他外設(硬件)的場景。詳細流程如下:

1、建立中心角色

2、掃描外設

3、發現外設

4、連接外設:

? ? 1.連接失敗

? ? 2. 連接斷開

? ? 3.連接成功

5、掃描外設中的服務

? ? 1.發現并獲取外設中的服務Service

6、掃描外設對應服務的特征

? ? 1.發現并獲取外設對應服務的特征Characteristic

? ? 2.給對應特征寫數據

? ? 3.訂閱特征的通知 7.1 根據特征讀取數據

說明:Service,Characteristic是每個硬件設備出廠設定的設備服務和特征值,用UUID作為唯一標識符。UUID為這種格式:0000ffe1-0000-1000-8000-00805f9b34fb。比如有3個Service,那么就有三個不同的UUID與Service對應。這些UUID都寫在硬件里,我們通過BLE提供的API可以讀取到,一個BLE終端可以包含多個Service, 一個Service可以包含多個Characteristic,一個Characteristic包含一個value和多個Descriptor,一個Descriptor包含一個Value。Characteristic是比較重要的,是手機與BLE終端交換數據的關鍵,讀取設置數據等操作都是操作Characteristic的相關屬性。說白了,我們可以把每個服務特征值看成是我們網絡請求的api接口,我們和藍牙的交互,是要連接到對應的service和對應的Characteristic才可以正確讀取到和硬件文檔以及出廠定制好的服務和數據。

三、CBPeriphera

暫且把這個小可愛理解為你所能發現搜索到的外設(硬件)對象,藍牙硬件的信息都包含在它里面

下面我們看下這個類所包含的內容:

CB_EXTERN_CLASS @interface CBPeripheral : CBPeer

//代理

@property(weak, nonatomic, nullable) id<CBPeripheralDelegate> delegate;

//我們所能搜索到的外設名稱

@property(retain, readonly, nullable) NSString *name;

//信號強度

@property(retain, readonly, nullable) NSNumber *RSSI;

//設備狀態,包含以下4種狀態

@property(readonly) CBPeripheralState state;

typedef NS_ENUM(NSInteger, CBPeripheralState) {

CBPeripheralStateDisconnected = 0,

CBPeripheralStateConnecting,

CBPeripheralStateConnected,

CBPeripheralStateDisconnecting

}

//服務群組

@property(retain, readonly, nullable) NSArray<CBService *> *services;

由于函數和屬性太多,我只列舉主要的幾個,其他的可在代碼中點擊查看即可

四、使用步驟概要

1、導入:#import <CoreBluetooth/CoreBluetooth.h>

2、遵守CBCentralManagerDelegate,CBPeripheralDelegate協議

3、初始化中心Manager,創建中心角色

為了方便引用,一般把manager聲明為一個屬性對象:

@property (nonatomic, strong) CBCentralManager * centralManager;

?self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

注:queue為你想把藍牙初始化放到哪個隊列,一般默認主隊列

? ? ? ? options傳nil即可,具體使用可查看策略含義

4、檢查當前設備中心的藍牙狀態

// 狀態更新時調用

- (void)centralManagerDidUpdateState:(CBCentralManager *)central

{

? ? switch (central.state) {

? ? ? ? case CBManagerStateUnknown:{

? ? ? ? ? ? NSLog(@"為知狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case CBManagerStateResetting:

? ? ? ? {

? ? ? ? ? ? NSLog(@"重置狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case CBManagerStateUnsupported:

? ? ? ? {

? ? ? ? ? ? NSLog(@"不支持的狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case CBManagerStateUnauthorized:

? ? ? ? {

? ? ? ? ? ? NSLog(@"未授權的狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case CBManagerStatePoweredOff:

? ? ? ? {

? ? ? ? ? ? NSLog(@"關閉狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case CBManagerStatePoweredOn:

? ? ? ? {

? ? ? ? ? ? NSLog(@"開啟狀態-可用狀態");

? ? ? ? ? ? self.peripheralState = central.state;

? ? ? ? ? ? NSLog(@"%ld",(long)self.peripheralState);

? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? default:

? ? ? ? ? ? break;

? ? }

}

5、開始掃描

if (self.peripheralState == CBManagerStatePoweredOn){

[self.centralManager scanForPeripheralsWithServices:nil options:nil];

}

6、發現外設

/**

掃描到設備

@param central 中心管理者

@param peripheral 掃描到的設備

@param advertisementData 廣告信息

@param RSSI 信號強度

*/

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI

{

? ? NSLog(@"%@",[NSString stringWithFormat:@"發現設備,設備名:%@",peripheral.name]);

}

7、連接外設

[self.centralManager connectPeripheral:peripheral options:nil];

? ? ? 連接狀態

/**

@param central 中心管理者

@param peripheral 連接失敗的設備

@param error 錯誤信息

*/

**?連接失敗 **

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

{

? ? NSLog(@"%@",@"連接失敗");

}

** 連接斷開 **

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

NSLog(@"%@",@"斷開連接");

?}

** 連接成功 **?

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {?

NSLog(@"連接設備:%@成功",peripheral.name);

?[self.centralManager stopScan];?

}

8、掃描外設服務Service

// 設置設備的代理

peripheral.delegate = self;

// services:傳入nil? 代表掃描所有服務

[peripheral discoverServices:nil];

/**

掃描到服務

@param peripheral 服務對應的設備

@param error 掃描錯誤信息

*/

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error

{

? ? // 遍歷所有的服務

? ? for (CBService *service in peripheral.services)

? ? {

? ? ? ? NSLog(@"服務:%@",service.UUID.UUIDString);

? ? }

}

9、掃描service特征值

kWriteServerUUID 為和廠家協定好的,

例:讀取電量的UUID:08B07DCB-13DD-435C-8BDA-04DA65BDC6AA

// 獲取對應的服務

? ? ? ? if (![service.UUID.UUIDString isEqualToString:kWriteServerUUID])

? ? ? ? {

? ? ? ? ? ? return;

? ? ? ? }

? ? ? ? // 根據服務去掃描特征

? ? ? ? [peripheral discoverCharacteristics:nil forService:service];

10、給特征值寫數據(就是發送指令)

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];

11、訂閱特征值通知(訂閱后可收到回應的數據)

if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]){

? [peripheral setNotifyValue:YES forCharacteristic:characteristic];

}

12、根據特征值讀取數據(注:應把之前發送數據和訂閱通知的peripheral和characteristic定義為全局屬性)

*該處即為接收到外設發送的數據的方法

/**

根據特征讀到數據

@param peripheral 讀取到數據對應的設備

@param characteristic 特征

@param error 錯誤信息

*/

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error

{

? ? if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])

? ? {

? ? ? ? NSData *data = characteristic.value;

? ? ? ? NSLog(@"%@",data);

? ? }

}

到這里,整個藍牙使用的核心流程就基本介紹完了,鑒于寫博客文章太累,太耗時,我決定先睡覺去,回頭把文章慢慢細化一下,查漏補缺,格式可能也不是很完美,請讀者們見諒,多提寶貴意見,喜歡的老鐵們,可以點下喜歡或者收藏!

打個廣告

本人github地址:shLuckySeven

歡迎去點star

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 這里我們具體說明一下中心模式的應用場景。主設備(手機去掃描連接外設,發現外設服務和屬性,操作服務和屬性的應用。一般...
    丶逝水流年閱讀 2,289評論 3 4
  • 本文主要以藍牙4.0做介紹,因為現在iOS能用的藍牙也就是只僅僅4.0的設備 用的庫就是core bluetoot...
    暮雨飛煙閱讀 865評論 0 2
  • 我的小姑子最近失戀了,整個人的精神一下子都垮掉了,整日萎靡不振,睡眼惺忪。正常的工作一天,下班就叫著累死了,推掉了...
    李若桃閱讀 322評論 1 1
  • 02 今天,我剛下朝,貼身太監突然撲通一聲給我跪了。“皇皇.....皇上,皇皇.....皇后她....她........
    琉璃信月閱讀 190評論 0 0
  • 笑來老師告訴我們:“人最寶貴的是注意力。”這句話當時不知點燃了多少人,因為當你啟動元認知能力的時候,就會知道自己浪...
    七公愛吃雞閱讀 408評論 0 0