藍牙是一個標准的無線通訊協議,具有設備成本低、傳輸距離近和功耗低等特點,被廣泛的應用在多種場合。藍牙一般分為傳統藍牙和BLE
兩種模式:傳統藍牙可以傳輸音頻等較大數據量,距離近、功耗相對大;而BLE
則用來傳輸節點數據,傳輸數據量十分小,多數情況處於休眠狀態,因而功耗十分低,被廣泛的應用於智能穿戴設備。
藍牙BLE簡介
本文主要介紹iOS
的藍牙BLE
開發流程,在介紹具體開發流程之前,有必要了解一下藍牙BLE
的特點。BLE
通過屬性(attribute
)在client
和server
之間進行數據交互,GATT
定義了屬性協議(Profile
)來進行發現設備、讀寫數據和獲取狀態等功能。其中,在iOS
藍牙BLE
開發過程中,App
應用屬於Central
設備,BLE
產品屬於外設Peripheral
。Profile
的結構圖如下:
其中,Service
和 Characteristic
都有一個UUID
來相互區分,類似心跳、血糖等的Service
的UUID
由藍牙SIG
統一設定,同時也允許自定義服務,但仍需要用不同的UUID
來標識。
針對客戶端藍牙BLE開發,一般不需要深入了解藍牙協議棧,如果有興趣,可以參考如下資料(本資料來自TI
):
TI_BLE_Description
BLE開發流程
1. 創建CBCentralManager
創建一個隊列,然后在這個隊列里面進行BLE
的各種操作
//創建CBCentralManager對象
dispatch_queue_t queue = dispatch_queue_create("bluetooth", DISPATCH_QUEUE_SERIAL);
CBCentralManager *mgr = [[CBCentralManager alloc] initWithDelegate:self queue:queue];
2. 掃描外設
參數介紹:
- serviceUUIDs: 指定掃描包含特點服務的外設,傳nil表明是所有服務
- options: 掃描時的設置,是一個字典
//CBCentralManagerScanOptionAllowDuplicatesKey值為 No,表示不重復掃描已發現的設備
NSDictionary *optionDic = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
[_mgr scanForPeripheralsWithServices:nil options:optionDic];
3. 停止掃描
[_mgr stopScan];
4. 連接外設
遍歷掃描到的外設,然后連接外設
for (CBPeripheral *peripheral in self.peripherals) {
[_mgr connectPeripheral:peripheral options:nil];
}
5. 掃描外設中的服務和特征
獲取服務
[peripheral discoverServices:nil];
獲取特征
[peripheral discoverCharacteristics:nil forService:service];
獲取描述
[peripheral discoverDescriptorsForCharacteristic:characteristic]
改寫特征數據
[_peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
6. 部分CBCentralManagerDelegate方法簡介
代理方法:centralManagerDidUpdateState
Central
已經更新狀態,要在CBManagerStatePoweredOn
里掃描外設,因為這是藍牙初始化工作已完成
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case CBManagerStatePoweredOn:
{
NSLog(@"開啟藍牙, 開始掃描");
[_mgr scanForPeripheralsWithServices:nil options:nil];
}
break;
case CBManagerStateUnsupported:
NSLog(@"不支持藍牙");
break;
case CBManagerStatePoweredOff:
NSLog(@"藍牙未打開");
break;
default:
NSLog(@"藍牙打開失敗");
break;
}
}
代理方法: centralManager:didDiscoverPeripheral:advertisementData:RSSI:
掃描到外設
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
代理方法: centralManager:didConnectPeripheral:
連接到外設
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
7. 部分CBPeripheralDelegate方法簡介
代理方法: peripheral:didDiscoverServices:
發現服務
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
代理方法: peripheral:didDiscoverCharacteristicsForService:error:
發現服務的特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
代理方法: peripheral:didUpdateValueForCharacteristic:error:
已經更新特征的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
代理方法: peripheral:didWriteValueForCharacteristic:error:
已經寫入特征的值
-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
8. 實例代碼
下面的視圖是基於小米手環2的測試數據,由於不是小米手環的開發者,沒辦法讀取詳細的數據,只把硬件、軟件的版本信息等數據讀出,以供需要開發藍牙BLE之參考。
參考源碼
https://github.com/BirdandLion/iOS-BLE.git
參考文檔
http://www.jianshu.com/p/0a6c49922aad