日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS蓝牙开发CoreBluetooth快速入门

發(fā)布時(shí)間:2024/4/17 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS蓝牙开发CoreBluetooth快速入门 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在iOS開發(fā)中,實(shí)現(xiàn)藍(lán)牙通信有兩種方式,一種是使用傳統(tǒng)的GameKit.framework,另一種就是使用在iOS 5中加入的CoreBluetooth.framework。

利用CoreBluetooth框架,我們可以輕松實(shí)現(xiàn)兩個iOS設(shè)備、iOS設(shè)備與非iOS藍(lán)牙設(shè)備的交互。要注意的一點(diǎn)是目前這個框架只能支持藍(lán)牙4.0BLE標(biāo)準(zhǔn),所以對硬件上是有一定要求的,iPhone 4S及以后的設(shè)備,第三代iPad及以后的設(shè)備是支持這一標(biāo)準(zhǔn)的。

術(shù)語解釋

我們首先看一下CoreBluetooth框架的結(jié)構(gòu)。這是CoreBluetooth/CoreBluetooth.h文件中的聲明。

1 2 3 4 #ifndef?_CORE_BLUETOOTH_H_ #define?_CORE_BLUETOOTH_H_ #endif #import?#import?#import?#import?#import?#import?#import?#import?#import?#import?#import

其中,CBCentral開頭的都是中心設(shè)備類,CBPeripheral開頭的都是外設(shè)類。這就要講到藍(lán)牙設(shè)備的兩個角色了。

  • 中心設(shè)備:中心設(shè)備可以理解為是處理數(shù)據(jù)的iOS設(shè)備,比如你的 iPhone、iPad 等。

  • 外設(shè):外設(shè)顧名思義,就是產(chǎn)生數(shù)據(jù)的外部設(shè)備。這個外部設(shè)備可以是單片機(jī)、嵌入式設(shè)備甚至是另一個iOS設(shè)備等等。外設(shè)可以通過其傳感器等產(chǎn)生有用數(shù)據(jù),數(shù)據(jù)后通過藍(lán)牙傳給中心設(shè)備使用。

在建立連接的之前,外設(shè)向外發(fā)出廣播數(shù)據(jù)(advertisementData,官方描述“A dictionary containing any advertisement and scan response data.”),廣播數(shù)據(jù)是一個字典類數(shù)據(jù),中心設(shè)備可以獲取一定范圍內(nèi)的外設(shè)發(fā)出的廣播數(shù)據(jù)。

現(xiàn)在開始

初始化

為了使用CoreBluetooth框架中的回調(diào)方法,我們要使用CBCentralManagerDelegate、CBPeripheralDelegate這兩個協(xié)議。

我們先要初始化一個CBCentralManager類的對象。代碼如下:

1 2 3 4 5 6 7 @interface?SKBluetoothManager?:?NSObject{ ????CBCentralManager?*manager; ????id?delegate; } manager?=?[[CBCentralManager?alloc]?initWithDelegate:self?queue:nil]; manager.delegate?=?self;

掃描外設(shè)

初始化完成,我們就可以讓管理器開始掃描外設(shè)了:

1 [manager?scanForPeripheralsWithServices:nil?options:nil];

在設(shè)備發(fā)現(xiàn)周圍外設(shè)的advertisementData后,會回調(diào)這個方法:

1 -?(void)centralManager:(CBCentralManager?*)central?didDiscoverPeripheral:(CBPeripheral?*)peripheral?advertisementData:(NSDictionary?*)advertisementData?RSSI:(NSNumber?*)RSSI;

其中參數(shù)central指回調(diào)這個方法的中心設(shè)備,peripheral指發(fā)現(xiàn)的外設(shè)對象CBPeripheral,advertisementData就是前面說的字典類型廣播數(shù)據(jù),RSSI是當(dāng)前外設(shè)的信號強(qiáng)度,單位是dbm。

剛開始對陌生的藍(lán)牙設(shè)備調(diào)試時(shí),建議我們先用一個數(shù)組NSArray將所掃描到的外設(shè)進(jìn)行保存:

1 [_peripherals?addObject:peripheral];

連接外設(shè)

保存后,可根據(jù)設(shè)備的UUID來確定該設(shè)備是否為我們需要進(jìn)行操作的藍(lán)牙設(shè)備,在確認(rèn)外設(shè)身份后,即可發(fā)起對外設(shè)的連接操作:

1 2 3 4 5 6 if?([peripheral.identifier.UUIDString?isEqualToString:kPeripheralUUID])?{ ????[manager?stopScan]; ????[manager?connectPeripheral:peripheral?options:nil]; ????NSLog(@"連接外設(shè):%@",peripheral.description); ????self.peripheral?=?peripheral; }

在此步操作后,我們完成了對藍(lán)牙設(shè)備的掃描工作,接下來的回調(diào)方法分為兩種情況:

連接到外設(shè)后

1 2 3 4 5 6 -?(void)centralManager:(CBCentralManager?*)central?didConnectPeripheral:(CBPeripheral?*)peripheral{ ????NSLog(@"已經(jīng)連接到:%@",?peripheral.description); ????peripheral.delegate?=?self; ????[central?stopScan]; ????[peripheral?discoverServices:nil]; }

一旦連接好外設(shè),我們就可以馬上停止掃描。然后發(fā)起對服務(wù)的搜索:

1 -?(void)discoverServices:(NSArray?*)serviceUUIDs;

此處參數(shù)位需要掃描的服務(wù)的UUID的數(shù)組。文檔中特別提到,若該參數(shù)為nil,將會掃描所有的服務(wù)。

連接失敗后

在連接外設(shè)失敗的回調(diào)方法中,提供了error參數(shù),可根據(jù)實(shí)際需要來做異常處理,在此不做過多說明

1 2 3 -?(void)centralManager:(CBCentralManager?*)central?didFailToConnectPeripheral:(CBPeripheral?*)peripheral?error:(NSError?*)error?{ ????NSLog(@"連接%@失敗",peripheral); }

在搜索到藍(lán)牙設(shè)備的服務(wù)后,將會回調(diào)

1 -?(void)peripheral:(CBPeripheral?*)peripheral?didDiscoverServices:(NSError?*)error

若有錯誤發(fā)生,通過NSError異常處理。

掃描服務(wù)

由于服務(wù)在peripheral里是以NSArray的形式存在的,所以我們要對peripheral中的所有服務(wù)進(jìn)行遍歷:

1 2 3 4 5 6 7 8 for?(CBService?*service?in?peripheral.services)?{ ????//發(fā)現(xiàn)服務(wù) ????if?([service.UUID?isEqual:[CBUUID?UUIDWithString:kServiceUUID]])?{ ????????NSLog(@"發(fā)現(xiàn)服務(wù):%@",?service.UUID); ????????[peripheral?discoverCharacteristics:nil?forService:service]; ????????break; ????} }

掃描特征值

在遍歷中,趁熱打鐵,直接對其特征值進(jìn)行掃描,

1 [peripheral?discoverCharacteristics:nil?forService:service];

這里與掃描service是相同的,若掃描所有的特征值,直接傳入nil作為參數(shù)即可。

這里的kServiceUUID是我們根據(jù)藍(lán)牙設(shè)備的具體情況,提前設(shè)置好的UUID常量。本文所有kXxxxxUUID均為預(yù)設(shè)的UUID常量。

同樣的,characteristics也是一個數(shù)組,我們利用像遍歷services一樣的方式來遍歷所有的特征值。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -?(void)peripheral:(CBPeripheral?*)peripheral?didDiscoverCharacteristicsForService:(CBService?*)service?error:(NSError?*)error?{ ????if?(error)?{ ????????NSLog(@"搜索特征%@時(shí)發(fā)生錯誤:%@",?service.UUID,?[error?localizedDescription]); ????????return; ????} ????NSLog(@"服務(wù):%@",service.UUID); ????for?(CBCharacteristic?*characteristic?in?service.characteristics)?{ //????????NSLog(@"特征:%@",characteristic); ????????//發(fā)現(xiàn)特征 ????????if?([characteristic.UUID?isEqual:[CBUUID?UUIDWithString:kCharacteristicWriteUUID]])?{ ????????????_writeCharacteristic?=?characteristic; ????????} ????????if?([characteristic.UUID?isEqual:[CBUUID?UUIDWithString:kCharacteristicNotifyUUID]])?{ ????????????NSLog(@"監(jiān)聽特征:%@",characteristic);//監(jiān)聽特征 ????????????[self.peripheral?setNotifyValue:YES?forCharacteristic:characteristic]; ????????????_isConnected?=?YES; ????????} ????} }

特別要提到的是,我們不同的藍(lán)牙設(shè)備有不同的服務(wù)和特征值。我的藍(lán)牙模塊的說明文檔中已經(jīng)說清楚了,write特征、read特征、notify特征,所以在此根據(jù)自身需要,來對不同的特征值進(jìn)行操作。

設(shè)置監(jiān)聽

我在此要解釋一下,當(dāng)我們試圖去讀取藍(lán)牙外設(shè)發(fā)過來的數(shù)據(jù)時(shí),一定要找準(zhǔn)特征值,用這個方法進(jìn)行訂閱。每次特征值變化的時(shí)候,就會有回調(diào)方法執(zhí)行,從而達(dá)到讀取數(shù)據(jù)的目的。容易出錯誤,一定分清楚到底哪個特征值該被訂閱。

在訂閱了特征值后,我們嘗試用藍(lán)牙外設(shè)發(fā)送一些數(shù)據(jù)出來,即可回調(diào)下一階段的方法:

1 2 3 4 5 6 7 8 9 -?(void)peripheral:(CBPeripheral?*)peripheral?didUpdateValueForCharacteristic:(CBCharacteristic?*)characteristic?error:(NSError?*)error?{ ????if?(error)?{ ????????NSLog(@"更新特征值%@時(shí)發(fā)生錯誤:%@",?characteristic.UUID,?[error?localizedDescription]); ????????return; ????} //?收到數(shù)據(jù) ????[delegate?didGetDataForString:[self?hexadecimalString:characteristic.value]]; //????NSLog(@"%@",[self?hexadecimalString:characteristic.value]); }

數(shù)據(jù)的轉(zhuǎn)換

我們接收到的數(shù)據(jù),正是characteristic.value,這是一個NSData類數(shù)據(jù),我們可以通過UTF8StringEncoding來轉(zhuǎn)化為NSString,為了代碼結(jié)構(gòu)清晰,我專門把NSData和NSString互轉(zhuǎn)寫成了兩個方法:

1 2 3 4 5 6 7 8 9 10 //將傳入的NSData類型轉(zhuǎn)換成NSString并返回 -?(NSString*)hexadecimalString:(NSData?*)data{ ????NSString?*result?=?[[NSString?alloc]?initWithData:data?encoding:NSUTF8StringEncoding]; ????return?result; } //將傳入的NSString類型轉(zhuǎn)換成NSData并返回 -?(NSData*)dataWithHexstring:(NSString?*)hexstring{ ????NSData?*aData; ????return?aData?=?[hexstring?dataUsingEncoding:?NSASCIIStringEncoding]; }

在拿到字符串后,通過各種回調(diào)方法,處理UI變動。

封裝的 SKBluetooth 的地址:SKBluetooth

轉(zhuǎn)載于:https://www.cnblogs.com/weiboyuan/p/6101296.html

總結(jié)

以上是生活随笔為你收集整理的iOS蓝牙开发CoreBluetooth快速入门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。