最近新接手智能硬件的項目,要用到ios藍牙,接下來把最近收集的資料和查到的相關信息分享給大家,劃分爲一下幾個方面
1. ios藍牙庫的基本介紹-CoreBluetooth
2. CoreBluetooth使用詳解
3. 相關問題
1. ios藍牙庫的基本介紹-CoreBluetooth
首先熟悉相關名詞:Central(中心設備)、Peripheral(外圍設備)、advertising(廣告)、Services(服務)、Characteristic(特徵)
Central:自己的設備(藍牙)
- CBCentralManager
Peripheral:搜索到的設備
- CBPeripheral
advertising:掃描到外圍設備時,外圍設備所攜帶的相關信息(有字節長度限制,這
些信息一般都是設備的相關信息)
- (NSDictionary *)advertisementData
Services:外圍設備的服務
- CBService
Characteristic:外圍設備的的特徵(可以理解爲發現相關服務後,服務下的特徵)
- CBCharacteristic
2. CoreBluetooth使用詳解
- .h 導入頭文件,設置代理
#import <CoreBluetooth/CoreBluetooth.h>
<CBCentralManagerDelegate,CBPeripheralDelegate>
- 初始化藍牙
self.manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
self.manager.delegate = self;
self.BleViewPerArr = [[NSMutableArray alloc]initWithCapacity:1];
- 開始掃描
-(void)scan{
//判斷狀態開始掃瞄周圍設備 第一個參數爲空則會掃瞄所有的可連接設備 你可以
//指定一個CBUUID對象 從而只掃瞄註冊用指定服務的設備
//scanForPeripheralsWithServices方法調用完後會調用代理CBCentralManagerDelegate的
//- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法
[self.manager scanForPeripheralsWithServices:nil options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];
//記錄目前是掃描狀態
_bluetoothState = BluetoothStateScaning;
//清空所有外設數組
[self.BleViewPerArr removeAllObjects];
//如果藍牙狀態未開啓,提示開啓藍牙
if(_bluetoothFailState==BluetoothFailStateByOff)
{
NSLog(@"%@",@"檢查您的藍牙是否開啓後重試");
}
}
- CBCentralManagerDelegate方法-藍牙狀態檢測
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if (central.state != CBCentralManagerStatePoweredOn) {
NSLog(@"fail, state is off.");
switch (central.state) {
case CBCentralManagerStatePoweredOff:
NSLog(@"連接失敗了\n請您再檢查一下您的手機藍牙是否開啓,\n然後再試一次吧");
_bluetoothFailState = BluetoothFailStateByOff;
break;
case CBCentralManagerStateResetting:
_bluetoothFailState=BluetoothFailStateByTimeout;
break;
case CBCentralManagerStateUnsupported:
NSLog(@"檢測到您的手機不支持藍牙4.0\n所以建立不了連接.建議更換您\n的手機再試試。");
_bluetoothFailState = BluetoothFailStateByHW;
break;
case CBCentralManagerStateUnauthorized:
NSLog(@"連接失敗了\n請您再檢查一下您的手機藍牙是否開啓,\n然後再試一次吧");
_bluetoothFailState = BluetoothFailStateUnauthorized;
break;
case CBCentralManagerStateUnknown:
_bluetoothFailState = BluetoothFailStateUnKnow;
break;
default:
break;
}
return;
}
_bluetoothFailState = BluetoothFailStateUnExit;
// ... so start scanning
}
- CBCentralManagerDelegate方法-發現周圍設備
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/)
{
return;
}
NSString *pername=[NSString stringWithFormat:@"%@",peripheral.name];
//判斷是否存在@"你的設備名"
NSRange range=[pername rangeOfString:@"你的設備名"];
//如果從搜索到的設備中找到指定設備名,和BleViewPerArr數組沒有它的地址
//加入BleViewPerArr數組
if(range.location!=NSNotFound&&[_BleViewPerArr containsObject:peripheral]==NO){
[_BleViewPerArr addObject:peripheral];
}
_bluetoothFailState = BluetoothFailStateUnExit;
_bluetoothState = BluetoothStateScanSuccess;
}
advertisementData即爲藍牙的廣播信息,打印信息如下(不同設備攜帶數據不同,打印查看,或在硬件文檔中查看相關key與value)
{
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = "brand";
kCBAdvDataTxPowerLevel = 2;
}
- 掃描到設備後連接相關設備
//連接設備,調用此方法,peripheral即爲存放在數組中的需要連接的設備(根據自己的需要,判斷要連接的設備,取出後調用此方芳連接)
[_manager connectPeripheral:peripheral
options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}];
- CBCentralManagerDelegate方法-連接上該設備
// 獲取當前設備
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"%@",peripheral);
// 設置設備代理
[peripheral setDelegate:self];
// 大概獲取服務和特徵
[peripheral discoverServices:nil];
//或許只獲取你的設備藍牙服務的uuid數組,一個或者多個
//[peripheral discoverServices:@[[CBUUID UUIDWithString:@""],[CBUUID UUIDWithString:@""]]];
NSLog(@"Peripheral Connected");
[_manager stopScan];
NSLog(@"Scanning stopped");
_bluetoothState=BluetoothStateConnected;
}
注意:連接失敗會調用- (void)centralManager:(CBCentralManager )central didFailToConnectPeripheral:(CBPeripheral )peripheral error:(NSError )error*
- CBPeripheralDelegate方法-獲取服務
// 獲取當前設備服務services
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
NSLog(@"所有的servicesUUID%@",peripheral.services);
//遍歷所有service
for (CBService *service in peripheral.services)
{
NSLog(@"服務%@",service.UUID);
//找到你需要的servicesuuid
if ([service.UUID isEqual:[CBUUID UUIDWithString:@"你的設備服務的uuid"]])
{
//監聽它
[peripheral discoverCharacteristics:nil forService:service];
}
}
NSLog(@"此時鏈接的peripheral:%@",peripheral);
}
- CBCentralManagerDelegate方法-獲取特徵值 :特徵值有幾種不同的屬性(讀,寫等,可打印查看)
重點:(獲取特徵值後,可以訂閱這個特徵的通知,也可寫入信息到設備,這兩種操作均會返回信息,實現與藍牙設備的交互,看下面的內容)
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (error)
{
NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
return;
}
NSLog(@"服務:%@",service.UUID);
// 特徵
for (CBCharacteristic *characteristic in service.characteristics)
{
NSLog(@"%@",characteristic.UUID);
//發現特徵
//注意:uuid 分爲可讀,可寫,要區別對待!!!
//爲藍牙設備寫入信息
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特徵uuid"]])
{
NSLog(@"監聽:%@",characteristic);//監聽特徵
//保存characteristic特徵值對象
//以後發信息也是用這個uuid
_characteristic1 = characteristic;
[discoveredPeripheral writeValue:d1 forCharacteristic:characteristic1 type:CBCharacteristicWriteWithResponse];
}
//訂閱characteristic特徵值的通知
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特徵uuid"]])
{
// _characteristic2 = characteristic;
// [peripheral setNotifyValue:YES forCharacteristic:_characteristic2];
// NSLog(@"監聽:%@",characteristic);//監聽特徵
}
}
}
- CBCentralManagerDelegate方法-讀取返回的信息
(上段代碼中writeValue:爲設備寫入信息、setNotifyValue:訂閱_characteristic2的通知都會返回信息,返回的信息會在對應的代代理方法中獲取:代碼中打印的characteristic.value即爲返回值)
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{
if (error)
{
NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
return;
}
NSLog(@"收到的數據:%@",characteristic.value);
}
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error)
{
NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
return;
}
NSLog(@"收到的數據:%@",characteristic.value);
}
3. 相關問題
獲取藍牙設備的mac地址
由於框架中不帶獲取mac地址的相關api,不能像安卓一樣通過調用getadress方法獲取,ios通過向藍牙設備寫入信息,返回相關的mac地址。具體操作:硬件工程師把mac地址寫入指定的特徵,ios端調用writeValue:方法傳入硬件工程師指定的數據,通過didupdatevalue方法獲取到返回的mac地址實現手機與藍牙設備的綁定問題
實現手機與藍牙設備的綁定原理同獲取mac地址:寫入相關的手機信息,藍牙設備存儲了手機信息,didupdatevalue方法返回了成功的信息即實現了綁定
ps:有什麼問題,活着不明白的可在評論區留言或發送站內信,看到後定會及時回覆,畢竟都是一步一步踩坑過來的,後續碰到什麼問題,也會及時更新在3. 相關問題