藍牙4.0是低電量模式因此也叫4.0BLE。本文將使用iOS系統提供的CoreBluetooth框架。app
CoreBluetooth框架的核心實際上是兩個東西,peripheral和central, 能夠理解成外設和主設備(中心)。框架
左邊是主設備模式,即開發的app在手機上,手機鏈接其它硬件(外設);
右邊的是外設模式,手機做爲外設,其它硬件設備做爲主設備。本文只講主設備模式,這種應用場景是最多的。優化
外設peripheral(主設備模式下,與手機鏈接的硬件是peripheral,例如AppleWatch)、服務service、特徵值characteristic的關係以下:ui
每一個外設下都有多個服務,每一個服務裏面有多個特徵值。服務和特徵值都有一個惟一識別碼UUID。與特徵值交互的模式經常使用有三種:讀取(read)、寫入(write)、還有監聽(notify)。咱們須要根據與硬件工程師所訂的協議找到對應服務裏面的特徵值,讀取或寫入這個特徵值。例如,咱們須要知道外設的硬件的電量,咱們須要讀取約定好的服務裏的特徵值,來獲取電量。若是咱們須要向外設發送指令,只須要找到對應的特徵值,寫入數據。spa
這裏簡單介紹一下系統CoreBluetooth使用的方法及代理。以便對後面使用第三方庫LGBluetooth更好地理解及使用和修改第三方內部的方法符合業務場景需求。代理
1.創建主設備模式code
#import <CoreBluetooth/CoreBluetooth.h> CBCentralManager *manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];
2.掃描外設(discover)orm
//掃描設備 [manager scanForPeripheralsWithServices:nil options:nil]; //掃描到設備會進入方法 -(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;
3.鏈接外設(connect)blog
[manager connectPeripheral:peripheral options:nil]; //鏈接外設成功的委託 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral; //外設鏈接失敗的委託 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error; //斷開外設的委託 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;
4.掃描外設中的服務和特徵(discover)ip
- 4.1 獲取外設的services - 4.2 獲取外設的Characteristics,獲取Characteristics的值
//掃描到服務 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error; //找到服務後,掃描到服務裏面的特徵值 -(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error;
5.與外設作數據交互(字節處理)
//在特徵值寫數據 [peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
6.訂閱Characteristic的通知
//訂閱通知 [peripheral setNotifyValue:YES forCharacteristic:characteristic];
7.斷開鏈接(disconnect)
//斷開鏈接的回調 -(void)disconnectPeripheral:(CBCentralManager *)centralManager peripheral:(CBPeripheral *)peripheral { //中止掃描 [centralManager stopScan]; //斷開鏈接 [centralManager cancelPeripheralConnection:peripheral]; }
1.在Appdelegate初始化LGCentralManager
#import <LGBluetooth/LGBluetooth.h> [LGCentralManager sharedInstance]
2.對LGBlueTooth封裝一個類,用來處理業務的藍牙指令(CommunicationManager)
\\鏈接設備 - (void)connectPeripheral:(LGPeripheral *)peripheral completion:(CompletionBlock)block { self.lgPeripheral = peripheral; self.connectBlock = block; __weak CommunicationManager *weakSelf = self; [peripheral connectWithCompletion:^(NSError *error) { if (!error) { weakSelf.shouldRetryConnect = YES; [weakSelf setupServicesWithPeripheral:peripheral completion:block]; } else { block(NO); } }]; } \\鏈接設備成功後,遍歷外設的服務,保存約定好的須要讀寫的特徵值 - (void)setupServicesWithPeripheral:(LGPeripheral *)peripheral completion:(CompletionBlock)block { self.connectBlock = block; [self defaultCharacteristicSetting]; self.lgPeripheral = peripheral; __weak CommunicationManager *weakSelf = self; [peripheral discoverServicesWithCompletion:^(NSArray *services, NSError *error) { for (LGService *service in services) { NSLog(@"serve uuidString:%@", service.UUIDString); if ([service.UUIDString isEqualToString:kNewOperationService]) { [service discoverCharacteristicsWithCompletion:^(NSArray *characteristics, NSError *error) { for (LGCharacteristic *characteristic in characteristics) { NSLog(@"characteristic:%@", characteristic.UUIDString); if ([characteristic.UUIDString isEqualToString:kNewWriteCharacteristic]) { weakSelf.deviceNewWriteCharacterstic = characteristic; [weakSelf checkIfAllReady]; } else if ([characteristic.UUIDString isEqualToString:kNewNotifyCharacteristic]) { weakSelf.deviceNewNotifyCharacterstic = characteristic; [characteristic setNotifyValue:YES completion:nil onUpdate:^(NSData *data, NSError *error) { [weakSelf handleData:data]; [weakSelf checkIfAllReady]; }]; } else if ([characteristic.UUIDString isEqualToString:kNewReadCharacteristic]) { weakSelf.deviceNewReadCharacterstic = characteristic; [characteristic readValueWithBlock:^(NSData *data, NSError *error) { if (!error) { peripheral.macAddress = [self convertNewMacAddressWithData:data]; NSLog(@"mac data:%@", peripheral.macAddress); [weakSelf checkIfAllReady]; } }]; } } }]; } } }]; }
3.發送藍牙指令(OperationType是業務的藍牙指令枚舉,例如查電量、關機、重啓、設備版本信息、設備改名等指令)
- (void)performOperationType:(OperationType)operationType object:(id)object completionBlock:(OperationBlock)block { self.operationBlock = block; //根據不一樣的藍牙指令處理藍牙數據 NSData *data = [self dataWithOperationType:operationType object:object]; if (data == nil) { return; } //寫入特徵值 [self.writeCharacteristic writeValue:data completion:^(NSError *error) { NSLog(@"functionCode:%d",[self getFunctionCodeByOperationType:operationType]); if (!error) { NSLog(@"成功發送特徵值數據"); } }]; //以後會根據監聽約定好的特徵值返回到藍牙指令執行結果做進一步處理 }
感謝閱讀,但願對你們認識藍牙開發的思路有所幫助,藍牙裏面開發還涉及到更加複雜的功能及優化,譬如設備搜索篩選、設備重連實現、設備固件升級優化等,因爲時間關係,只做流程性的藍牙開發的介紹。謝謝。