引導(dǎo)語
人工智能自1956年提出以來,一直默默無聞,近年來人工智能的發(fā)展得到重視逐漸發(fā)展起步,智能硬件、智能手環(huán)、智能家居等等逐漸走進(jìn)人們的生活,大大方便人們的同時也帶來了全新的用戶體驗(yàn)和互聯(lián)網(wǎng)一個新的發(fā)展方向。
前言
最近公司也在做硬件設(shè)備,作為一名iOS開發(fā)人員,主要負(fù)責(zé)手機(jī)軟件、硬件的連接方面,開發(fā)連接硬件使用的SDK,其中主要模塊是藍(lán)牙連接,通過藍(lán)牙與硬件設(shè)備連接,發(fā)送指令使硬件工作。
功能說起來很簡單,但是尋找了好幾天的藍(lán)牙方面的Demo,看到了很多前人大神們封裝的Bluetooth方法,感覺對于我等小白實(shí)在是有點(diǎn)深奧,方法繁多,不知從何處下手。所以最后考慮再三,還是從底層基礎(chǔ)入手,自己重新整理、封裝了一份藍(lán)牙的查找、連接、寫入、斷開的類,本著程序員的開源精神,分享出來,歡迎大家指正。
下面 ,我對封裝類從功能方面分類進(jìn)行說明:
系統(tǒng)藍(lán)牙狀態(tài)監(jiān)聽
這個很方便,在系統(tǒng)藍(lán)牙方法centralManagerDidUpdateState中就可以實(shí)時獲取到藍(lán)牙狀態(tài)的改變,所以用一個Block回調(diào)就可以得到狀態(tài),根據(jù)狀態(tài)變化做對應(yīng)操作即可。
方法代碼如下:
/**
系統(tǒng)當(dāng)前藍(lán)牙的狀態(tài)
@paramstateBlock 實(shí)時返回當(dāng)前藍(lán)牙狀態(tài)
*/
- (void)returnBluetoothStateWithBlock:(FZStateUpdateBlock)stateBlock;
藍(lán)牙搜索
藍(lán)牙搜索的功能方法中,用系統(tǒng)原生的方法scanForPeripheralsWithServices:options:,在藍(lán)牙搜索的代理方法centralManager:didDiscoverPeripheral:advertisementData:RSSI:里獲取搜索結(jié)果,用Block返回搜索結(jié)果。另外添加了方法通過設(shè)置參數(shù)nameStr來篩選返回的設(shè)備名稱,nameStr為設(shè)備模糊搜索參數(shù),設(shè)備中包含nameStr字段即可返回搜索結(jié)果。
封裝后的代碼調(diào)用方法如下:
/*
* 開始搜索藍(lán)牙外設(shè),每次在block中返回一個藍(lán)牙外設(shè)信息
*@paramnameStr? 模糊搜索設(shè)備名稱,目標(biāo)設(shè)備名稱包含字段
*? 返回的block參數(shù)可參考CBCentralManager 的centralManager:didDiscoverPeripheral:advertisementData:RSSI:
*@paramdiscoverBlock 搜索到藍(lán)牙外設(shè)后的回調(diào)
*/
- (void)scanForPeripheralsWithPrefixName:(NSString *)nameStr discoverPeripheral:(FZDiscoverPeripheralBlock)discoverBlock;
藍(lán)牙設(shè)備的連接
藍(lán)牙的連接為系統(tǒng)方法connectPeripheral:options:,連接設(shè)備的結(jié)果分別通過代理方法centralManager:didConnectPeripheral:返回成功、centralManager:didFailToConnectPeripheral:error:返回失敗,通過兩個Block分別返回成功和失敗。其中成功后要停止搜索stopScan,失敗要返回失敗原因。
代碼方法如下:
/*
*? 連接某個藍(lán)牙外設(shè),并查詢服務(wù),特性,特性描述
*@paramperipheral? ? ? ? ? 要連接的藍(lán)牙外設(shè)
*@paramcompletionBlock? ? 操作執(zhí)行完的回調(diào)
*/
- (void)connectPeripheral:(CBPeripheral *)peripheral completeBlock:(FZConnectSuccessBlock)completionBlock failBlock:(FZConnectFailBlock)failBlock;
設(shè)備的自動連接設(shè)置
設(shè)備的自動連接,這里我寫了兩種方法,大家可以根據(jù)自己喜好自由選擇;
1.根據(jù)設(shè)備peripheral自動連接方法代碼如下:
/**
設(shè)置或刪除自動連接設(shè)備
設(shè)置后,在代理方法connectionWithPerpheral:里會返回設(shè)備的peripheral
@param setOrDel 自動連接和刪除自動連接
@param peripheral 設(shè)備peripheral
*/
-(void)createAutomaticConnectionEquipmenWithSetOrDelate:(AutomaticConnectionEquipmenEnum)setOrDel Peripheral:(CBPeripheral *)peripheral;
這個方法中setOrDel有兩個枚舉值,分別為:SetAutomaticConnectionEquipmen(設(shè)置自動重連)和DelateAutomaticConnectionEquipmen(刪除自動重連)。?
使用方法:?
設(shè)置自動重連設(shè)備后,這里傳入的peripheral會自動保存,服從代理:FZAutomaticConnectionDelegate,在代理方法
/**
自動連接的設(shè)備代理方法
*/
- (void)connectionWithPerpheral:(CBPeripheral *)peripheral;
中可以獲取到重連的設(shè)備peripheral,隨后進(jìn)行連接操作即可。
2.通過設(shè)備UUID自動連接
代碼方法如下:
/**
通過UUID獲取peripheral
用戶自主記錄想要自動連接的UUID,獲取peripheral后調(diào)用連接方法
@param UUIDString UUID
@return peripheral
*/
- (CBPeripheral *)retrievePeripheralWithUUIDString:(NSString *)UUIDString;
使用方法:?
獲取到設(shè)備的UUID后,通過此方法得到設(shè)備的peripheral,然后調(diào)用連接設(shè)備的方法即可自動重新連接。
寫入數(shù)據(jù)
寫入數(shù)據(jù),在大多數(shù)的第三方方法里會有UUID、characteristic、peripheral等很多參數(shù),混亂不易理解。這里我封裝后只留了一個characteristic特性參數(shù),而且已經(jīng)幫大家篩選出來了,可以在封裝方法頭文件里,連接設(shè)備成功后直接獲取到。另一方面,寫入內(nèi)容直接用NSString類型就可以,內(nèi)部會自動轉(zhuǎn)成NSData格式寫入設(shè)備。
寫入數(shù)據(jù)原生方法為writeValue:forCharacteristic:type:,寫入數(shù)據(jù)后會在代理方法peripheral:didWriteValueForCharacteristic:error:方法里得到是否寫入成功,成功與否用Block返回了結(jié)果。另外,如果藍(lán)牙設(shè)備有應(yīng)答的時候,會在peripheral:didUpdateValueForCharacteristic:error:方法里返回,處理起來比較麻煩,我下面封裝了兩種方法,一種通過Block異步返回結(jié)果,一種為同步返回應(yīng)答結(jié)果,大家可以根據(jù)需要自由選擇。
1.異步Block方式返回結(jié)果
代碼封裝后的接口為:
/*
*? 往某個特性中寫入數(shù)據(jù)
*@paramcharacteristic 特性對象
*@paramcompletionBlock 寫入完成后的回調(diào),只有type為CBCharacteristicWriteWithResponse時,才會回調(diào)
*/
- (void)writeValue:(NSString *)dataStr forCharacteristic:(CBCharacteristic *)characteristic completionBlock:(FZWriteToCharacteristicBlock)completionBlock returnBlock:(FZEquipmentReturnBlock)equipmentBlock;
2.同步返回結(jié)果
接口方法為:
/**
* 往某個特性中寫入數(shù)據(jù),同步返回結(jié)果?
* @param dataStr 寫入的數(shù)據(jù)
* @param characteristic 特性對象
* @return 設(shè)備應(yīng)答結(jié)果 returnStr 應(yīng)答內(nèi)容 error 錯誤信息
*/
-(NSDictionary *)writeValue:(NSString *)dataStr forCharacteristic:(CBCharacteristic *)characteristic;
同步返回的字典中有兩個參數(shù):returnStr和error,returnStr為設(shè)備應(yīng)答數(shù)據(jù),error為錯誤信息,判斷error為nil時為成功,取returnStr進(jìn)行下一步操作即可。
這里需要注意的是:實(shí)際開發(fā)中,可以用一個叫l(wèi)ightBlue的藍(lán)牙開發(fā)輔助APP,看一下設(shè)備有多少特征值,我們實(shí)際用的時候需要用哪個,這個可以直接詢問硬件廠商或硬件開發(fā)人員,然后在調(diào)用寫入方法前,設(shè)置封裝類中的屬性UUIDString的對應(yīng)值,可以保證連接過程中穩(wěn)定不出問題
藍(lán)牙的斷開
藍(lán)牙的斷開,只留了一個方法,斷開當(dāng)前連接的設(shè)備,使用系統(tǒng)原生方法cancelPeripheralConnection:,設(shè)備的信息在連接時已自動記錄,所以不需要傳入?yún)?shù)
代碼封裝后的方法如下:
/*
*? 斷開藍(lán)牙連接
*/
- (void)readRSSICompletionBlock:(FZGetRSSIBlock)getRSSIBlock;
其他
其他的方法,頭文件里開放了”RSSI轉(zhuǎn)距離Double類型數(shù)據(jù)”、”NSData轉(zhuǎn)16進(jìn)制字符串”、”NSString類型轉(zhuǎn)NSData類型數(shù)據(jù)”三個方法。
結(jié)束語
最后,代碼封裝類的源碼和Demo,我已經(jīng)放在了GitHub上,地址為:https://github.com/fuzheng0301/FZBluetooth,大家可以自由下載、使用,后續(xù)還會陸續(xù)更新部分常用功能,歡迎大家的指正、幫助。如果可以,感謝您的star,大家的支持是我不斷努力的堅(jiān)強(qiáng)后盾。