iOS 藍芽4.0開發使用(內附Demo)

FBY展菲發表於2019-03-26

一: 介紹

近幾年,智慧裝置越來越火,這些智慧裝置中,有很大一部分是通過手機來控制硬體裝置,來達到預期的效果,這中間少不了要使用到藍芽功能,通過藍芽來通訊來控制裝置。

藍芽分為藍芽2.0和藍芽4.0。 藍芽2.0為傳統藍芽,傳統藍芽也稱為經典藍芽。 藍芽4.0因為低耗電,所以也叫做低功耗藍(BLE),它將三種規格集一體,包括傳統藍芽技術、高速技術和低耗能技術。

這篇文章用來介紹BLE 4.0的使用以及相關問題的解決。

二:BLE的兩種模式

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

CBCentralMannager 中心模式

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

  1. 建立中心角色
  2. 掃描外設
  3. 發現外設
  4. 連線外設 4.1 連線失敗 4.2 連線斷開 4.3 連線成功
  5. 掃描外設中的服務 5.1 發現並獲取外設中的服務
  6. 掃描外設對應服務的特徵 6.1 發現並獲取外設對應服務的特徵 6.2 給對應特徵寫資料
  7. 訂閱特徵的通知 7.1 根據特徵讀取資料

CBPeripheralManager 外設模式

使用手機作為外設連線其他中心裝置操作的場景。 PS:因為蘋果裝置的安全性和封閉性,蘋果裝置不能通過與其他裝置藍芽連結進行檔案傳輸等功能,所以在iOS與藍芽開發的程式設計中是CBCentralMannager 中心模式程式設計居多.

  1. 建立外設角色
  2. 設定本地外設的服務和特徵
  3. 釋出外設和特徵
  4. 廣播服務
  5. 響應中心的讀寫請求
  6. 傳送更新的特徵值,訂閱中心

三:BLE開發步驟

在介紹CBCentralMannager 中心模式開發步驟之前,首先需要對專案進行如下配置:

#import "ESPFBYBLEHelper.h"
#import <CoreBluetooth/CoreBluetooth.h>

@interface ESPFBYBLEHelper ()<CBCentralManagerDelegate,CBPeripheralDelegate>
// 中心管理者(管理裝置的掃描和連線)
@property (nonatomic, strong) CBCentralManager *centralManager;
// 儲存的裝置
@property (nonatomic, strong) NSMutableArray *peripherals;
// 掃描到的裝置
@property (nonatomic, strong) CBPeripheral *cbPeripheral;
// 外設狀態
@property (nonatomic, assign) CBManagerState peripheralState;
@end

// 藍芽4.0裝置名
static NSString * const kBlePeripheralName = @"lighte290";
// 通知服務
static NSString * const kNotifyServerUUID = @"FF03";
// 寫服務
static NSString * const kWriteServerUUID = @"FFFF";
// 通知特徵值
static NSString * const kNotifyCharacteristicUUID = @"FF05";
// 寫特徵值
static NSString * const kWriteCharacteristicUUID = @"FF08";
@implementation ESPFBYBLEHelper
複製程式碼

這其中需要匯入CoreBluetooth框架

#import <CoreBluetooth/CoreBluetooth.h>
複製程式碼

遵守CBCentralManagerDelegate,CBPeripheralDelegate協議

@interface ESPFBYBLEHelper ()<CBCentralManagerDelegate,CBPeripheralDelegate>
複製程式碼

然後需要檢測藍芽狀態,程式碼如下:

// 狀態更新時呼叫
- (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;
    }
}
複製程式碼

新增屬性和常量,常量需要根據自己的專案來進行配置。 下面只需要根據實現流程一步步實現即可,核心程式碼如下:

1. 建立中心角色
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
複製程式碼
2. 掃描外設
if (self.peripheralState ==  CBManagerStatePoweredOn){
    [self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
複製程式碼
3. 發現外設
/**
 掃描到裝置
 @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]);
}
複製程式碼
4. 連線外設
[self.centralManager connectPeripheral:peripheral options:nil];
複製程式碼
  • 4.1 連線失敗 didFailToConnectPeripheral
/**
 連線失敗
 @param central 中心管理者
 @param peripheral 連線失敗的裝置
 @param error 錯誤資訊
 */
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"%@",@"連線失敗");
}
複製程式碼
  • 4.2 連線斷開
/**
 連線斷開
 @param central 中心管理者
 @param peripheral 連線斷開的裝置
 @param error 錯誤資訊
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"%@",@"斷開連線");
}
複製程式碼
  • 4.3 連線成功
/**
 連線成功
 
 @param central 中心管理者
 @param peripheral 連線成功的裝置
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"連線裝置:%@成功",peripheral.name);
    [self.centralManager stopScan];
}
複製程式碼
5. 掃描外設中的服務
// 設定裝置的代理
peripheral.delegate = self;
// services:傳入nil  代表掃描所有服務
[peripheral discoverServices:nil];
複製程式碼

5.1 發現並獲取外設中的服務

/**
 掃描到服務
 @param peripheral 服務對應的裝置
 @param error 掃描錯誤資訊
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // 遍歷所有的服務
    for (CBService *service in peripheral.services)
    {
        NSLog(@"服務:%@",service.UUID.UUIDString);
    }
}
複製程式碼
6. 掃描外設對應服務的特徵
        // 獲取對應的服務
        if (![service.UUID.UUIDString isEqualToString:kWriteServerUUID])
        {
            return;
        }
        // 根據服務去掃描特徵
        [peripheral discoverCharacteristics:nil forService:service];
複製程式碼

6.1 發現並獲取外設對應服務的特徵

/**
 掃描到對應的特徵
 @param peripheral 裝置
 @param service 特徵對應的服務
 @param error 錯誤資訊
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    NSLog(@"%@",peripheral);
}
複製程式碼

6.2 給對應特徵寫資料

[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
複製程式碼
7. 訂閱特徵的通知
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]){
  [peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
複製程式碼

7.1 根據特徵讀取資料 didUpdateValueForCharacteristic

/**
 根據特徵讀到資料
 @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);
    }
}
複製程式碼

四:原始碼Demo獲取方法

如果需要原始碼demo,歡迎關注 【網羅開發】微信公眾號,回覆【94】便可領取。 網羅天下方法,方便你我開發,所有文件會持續更新,歡迎關注一起成長!


歡迎關注公眾號「網羅開發」

iOS 藍芽4.0開發使用(內附Demo)

相關文章