前言
公司一直在做和 POS機的相關(guān)工作,就是廠家把 POS機器送給我們,我們把 POS機根據(jù)廠家的 SDK添加到我們自己的安卓和應(yīng)用程序上.安卓那邊老早就已經(jīng)封裝了一套自己藍牙的東西,統(tǒng)一搜索調(diào)用,很好管理.但是 iOS 端一直是分開使用廠家自帶的 SDK. 這種做法,最開始自己深知就是埋了一顆雷,果不其然,上周功能迭代,終于要求實現(xiàn)自動重連和綁定設(shè)備的功能模塊,自己封裝一套藍牙搜索工具類,成必須的了.
藍牙技術(shù), 在看iOS中目前提供了四個藍牙的實現(xiàn)方案.我自己知道的是 GameKit和 CoreBluttooth.但是這里因為我項目的原因,我這里只講到 CoreBluetooth相關(guān)的介紹標(biāo)題提到的那三小塊. 我們最常用的,最火熱的也正好是 CoreBluetooth.
看到這里,大家肯定覺得什么情況,就這么點東西.好在,天無絕人之路,這里隆重的推薦我的大學(xué)同學(xué)即SwiftGG翻譯組的 Miss.唐. Miss.唐在去年跑到深圳之后,就在一家藍牙硬件和軟件通訊的貌似是做玩具的公司開始了她輝煌的藍牙4.0生涯.我很早就看到她在個站上關(guān)于 CoreBluetooh 的文章,涵蓋了基礎(chǔ)的定義,搜索鏈接,自動重連,數(shù)據(jù)交互等等.各位看官完全可以在我這篇后,完全可以細讀Miss.唐的八篇文章,讀完,你做手頭的工作基本差不多了.
八篇CoreBluetooth 文章!讓你遨游在和藍牙4.0設(shè)備交互的海洋!!感謝 Miss.唐
當(dāng)然,大家看我的這篇文章再看上邊八篇,也是極好的.
今天的.....這篇前言好長....廢話好多!!!!!
iOS 中藍牙的四種實現(xiàn)方案
直接貼上某培訓(xùn)機構(gòu)的 PPT 截圖,足夠簡明,如下:

CoreBluetooth簡介
核心結(jié)構(gòu)

- 第一行中,
CBCentral和CBPeripheral即中心和周邊,這兩個是相對且角色可以互換的.最簡單的例子就是兩個手機. A手機(central)搜索連接到到 B手機(peripheral),也可以 B手機(central)搜索連接到到 A手機(peripheral).
同時,我們前邊提到藍牙設(shè)備之間的數(shù)據(jù)交換.CBPeripheral的CBCentral之間的數(shù)據(jù)交換是相互的.那就意味兩者其實都能夠彼此對對方發(fā)出的請求(我們這里叫做他們在發(fā)送廣播)做出響應(yīng),這就各自需要一個控制器類,即CBCentralManager 和 CBPeripheralManager.達到和對方'控制'和'溝通'的效果.
- 第二行中,
CBService和CBCharacteristic,是歸屬于CBPeripheral,每個周邊藍牙4.0設(shè)備就是通過服務(wù)(Service)和特征(Characteristic)來展示自己的.再或者引用 Miss唐原文中的話來說:
當(dāng)你操作 peripheral 的時候,實際上是在和它的 service 和 characteristic 打交道,這兩個分別由CBService和CBCharacteristic表示。
一個 CBPeripheral 包含多個 service,而一個 service 又可以包含多個 characteristic(前半句:service 可以包含 service 或者 characteristic。
后半句:service 本身的信息很少,更為詳細的 service 信息意思就是,它里面包含哪些 characteristic,然后 characteristic 的信息就作為 service 信息的補充。). 所以他們的關(guān)系大致可以表示為:
在設(shè)備充當(dāng)時,CBPeripheralManager這個類提供的主要方法則是對 service 的管理,同時還兼?zhèn)渲?central 廣播數(shù)據(jù)的功能. CBPeripheralManager處理的是可變的 service 和 characteristic,分別由CBMutableService和CBMutableCharacteristic表示
- 第三行中,
CBUUID和CBATTRequest.關(guān)于CBUUID,引自《iOS CoreBluetooth 教程》的一段描述,如下:
每一個服務(wù)和特征都需要用一個UUID(unique identifier)去標(biāo)識,UUID是一個16bit或者128bit的值。如果你要創(chuàng)建你的中央-周邊App,你需要創(chuàng)建你自己的128bit的UUID。你必須要確定你自己的UUID不能和其他已經(jīng)存在的服務(wù)沖突。如果你正要創(chuàng)建一個自己的設(shè)備,需要實現(xiàn)標(biāo)準委員會需求的UUID;如果你只是創(chuàng)建一個中央-周邊App(就像我們現(xiàn)在做的這樣),我建議你打開Mac OS X的Terminal.app,用uuidgen命令生成一個128bit的UUID。你應(yīng)該用該命令兩次,生成兩個UUID,一個是給服務(wù)用的,一個是給特征用的。然后,你需要添加他們到中央和周邊App中?,F(xiàn)在,在view controller的實現(xiàn)之前,我們添加以下的代碼:
>static NSString * const kServiceUUID = @"312700E2-E79-4D5C-8DCF-49908332DF9F";
static NSString * const kCharacteristicUUID = @"FFA28CDE-6525-4489-801C-1C060CAC9767";
注意:你自己用uuidgen生成的UUID和我的是不一樣的。
上邊提到的UUID,即是 CBUUID.另外,在scanForPeripheralsWithServices:options:方法中,我們還可以根據(jù) CBUUID 來指定@[UUID1,UUID2]的設(shè)備.
CBATTRequest是我們在對characteristics進行操作的時候,系統(tǒng)代理方法中的一個結(jié)果參數(shù).比如,下邊這個方法:
//讀characteristics請求
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
}
CoreBluetooth(搜索(自定義選擇列表)+連接+自動重連)
Demo 描述
Demo 已經(jīng)寫完了,這里和大家簡單說一下,這個 Demo 的流程.本來打算寫一個的,但是寫著寫著,發(fā)現(xiàn)還是 Miss.唐的 Demo 里的流程和我需求十分相近.雖然,有幾個地方我感覺到有點可疑,但是經(jīng)過測試和驗證之后,發(fā)現(xiàn) Miss.唐的已經(jīng)足夠正確.所以我的流程和她的基本相近,當(dāng)然,我也做了部分優(yōu)化,加入了自定義的類似 UIAlertView 的選擇列表框.
首先,工具類是繼承自 NSObject, 因為是自動重連還是重新搜索是每次執(zhí)行工具類,最先應(yīng)該判斷的,所以直接放到了初始化-(instancetype)init方法中,是否自動重連的依據(jù)就是本地偏好設(shè)置,是否保存了設(shè)備的 indentify.(這里要提依據(jù),我們搜索到的 CBPeripheral 對象中的 identify 屬性是描述藍牙設(shè)備唯一性的類似于 mac 地址的東西,但是也需要注意,不同的 iOS設(shè)備 連接同一個 peripheral 獲得的 identifier 是不一樣的,然而這并不影響我們確定唯一的設(shè)備). 如果自動重連,則執(zhí)行自動重連.如果不符合自動重連的條件,那么就執(zhí)行重新搜索或者其他你自己公司需求規(guī)定的處理代碼.
如果自動重連不成功,那么則我們可以進行搜索->連接的步驟.
主要方法
1.初始化中心管理者
//1. 創(chuàng)建中心設(shè)備管理者,并且設(shè)置代理
//初始化方式一:,不會提示出現(xiàn)"打開藍牙允許'xxxx'連接都配件"的系統(tǒng)提示
_myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];
//初始化方式二
_myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
2.獲取可以自動重連的設(shè)備
NSArray *resultArray = [NSArray arrayWithArray:[self.myCentralManager retrievePeripheralsWithIdentifiers:@[connentIdentify]]];
這個方法,是根據(jù)connentIdentify獲取到自動重連設(shè)備數(shù)組,然后選擇自動重連的設(shè)備(我的項目中只要求綁定一個設(shè)備),然后執(zhí)行連接設(shè)備.
3.連接設(shè)備
[self.myCentralManager connectPeripheral:peripheral options:nil];
4.搜索周邊藍牙設(shè)備
//搜索藍牙設(shè)備
[self.myCentralManager scanForPeripheralsWithServices:nil options:nil];
關(guān)于幾個彎兒
1.最開始做自動重連的時候,我思路是,必須得保證搜索到的設(shè)備里邊有需要自動重連的設(shè)備,我們才能夠進行自動重連.其實,我們在執(zhí)行retrievePeripheralsWithIdentifiers:然后選擇進行connectPeripheral:options:連接的時候,對應(yīng)的設(shè)備存在或者已經(jīng)打開開關(guān),是否連接成功就已經(jīng)能夠體現(xiàn)了.
另外,還有一種自動重連的思路就是:你還可以把自動重連的方法寫在搜索方法里邊.每次執(zhí)行搜索設(shè)備方法的時候,進行判斷,如果本地已經(jīng)有了保存的綁定設(shè)備,那么就優(yōu)先重新連接本地設(shè)備,如果沒有的話,那么搜索設(shè)備.
CoreBluetooth補充
CoreBluetooth 的基本常識

CoreBluetooth 的開發(fā)步驟

Demo
還是直接看 Demo吧.
我的 Demo地址:我的 Demo 地址
Miss.唐的Demo地址:Miss.唐的Demo地址
推薦文章
Miss.唐的八篇 CoreBluetooth 文章:
1.《CoreBluetooth1 初識》
2.《CoreBluetooth2 作為 Central 時的數(shù)據(jù)讀寫》
3.《CoreBluetooth3 作為 Central 時的數(shù)據(jù)讀寫(補充)》
4.《CoreBluetooth4 作為 Central 時的數(shù)據(jù)讀寫(最佳實踐》
5.《CoreBluetooth5 作為 Central 時的數(shù)據(jù)讀寫(OTA 固件升級與文件傳輸)》
6.《CoreBluetooth6 作為 Peripheral 時的請求響應(yīng)》
7.《CoreBluetooth7 作為 Peripheral 時的請求響應(yīng)(最佳實踐)》
8.《CoreBluetooth8 后臺運行藍牙服務(wù)》
另一番推薦劉彥瑋的寫的幾篇:
1.《【投稿】iOS藍牙開發(fā)(一)藍牙相關(guān)基礎(chǔ)知識》
2.《iOS 藍牙開發(fā)(二)iOS 連接外設(shè)的代碼實現(xiàn)》
3.《iOS 藍牙開發(fā)(三)app作為外設(shè)被連接的實現(xiàn)》
4.《iOS 藍牙開發(fā)(四)BabyBluetooth藍牙庫介紹》
其次,我還參考了,如下幾篇文章:

希望能和大家交流技術(shù)
GitHub:https://github.com/lilongcnc
