藍牙是一個標準的無線通訊協(xié)議,具有設備成本低、傳輸距離近和功耗低等特點,被廣泛的應用在多種場合。藍牙一般分為傳統(tǒng)藍牙和BLE兩種模式:傳統(tǒng)藍牙可以傳輸音頻等較大數(shù)據(jù)量,距離近、功耗相對大;而BLE則用來傳輸節(jié)點數(shù)據(jù),傳輸數(shù)據(jù)量十分小,多數(shù)情況處于休眠狀態(tài),因而功耗十分低,被廣泛的應用于智能穿戴設備。
藍牙BLE簡介
本文主要介紹iOS的藍牙BLE開發(fā)流程,在介紹具體開發(fā)流程之前,有必要了解一下藍牙BLE的特點。BLE通過屬性(attribute)在client和server之間進行數(shù)據(jù)交互,GATT定義了屬性協(xié)議(Profile)來進行發(fā)現(xiàn)設備、讀寫數(shù)據(jù)和獲取狀態(tài)等功能。其中,在iOS藍牙BLE開發(fā)過程中,App應用屬于Central設備,BLE產(chǎn)品屬于外設Peripheral。Profile的結構圖如下:

其中,Service 和 Characteristic 都有一個UUID來相互區(qū)分,類似心跳、血糖等的Service的UUID由藍牙SIG統(tǒng)一設定,同時也允許自定義服務,但仍需要用不同的UUID來標識。
針對客戶端藍牙BLE開發(fā),一般不需要深入了解藍牙協(xié)議棧,如果有興趣,可以參考如下資料(本資料來自TI):
TI_BLE_Description
BLE開發(fā)流程
1. 創(chuàng)建CBCentralManager
創(chuàng)建一個隊列,然后在這個隊列里面進行BLE的各種操作
//創(chuàng)建CBCentralManager對象
dispatch_queue_t queue = dispatch_queue_create("bluetooth", DISPATCH_QUEUE_SERIAL);
CBCentralManager *mgr = [[CBCentralManager alloc] initWithDelegate:self queue:queue];
2. 掃描外設
參數(shù)介紹:
- serviceUUIDs: 指定掃描包含特點服務的外設,傳nil表明是所有服務
- options: 掃描時的設置,是一個字典
//CBCentralManagerScanOptionAllowDuplicatesKey值為 No,表示不重復掃描已發(fā)現(xiàn)的設備
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]
改寫特征數(shù)據(jù)
[_peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
6. 部分CBCentralManagerDelegate方法簡介
代理方法:centralManagerDidUpdateState
Central已經(jīng)更新狀態(tài),要在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:
發(fā)現(xiàn)服務
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
代理方法: peripheral:didDiscoverCharacteristicsForService:error:
發(fā)現(xiàn)服務的特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
代理方法: peripheral:didUpdateValueForCharacteristic:error:
已經(jīng)更新特征的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
代理方法: peripheral:didWriteValueForCharacteristic:error:
已經(jīng)寫入特征的值
-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
8. 實例代碼
下面的視圖是基于小米手環(huán)2的測試數(shù)據(jù),由于不是小米手環(huán)的開發(fā)者,沒辦法讀取詳細的數(shù)據(jù),只把硬件、軟件的版本信息等數(shù)據(jù)讀出,以供需要開發(fā)藍牙BLE之參考。
參考源碼
https://github.com/BirdandLion/iOS-BLE.git
參考文檔
http://www.itdecent.cn/p/0a6c49922aad