iOS 藍(lán)牙開(kāi)發(fā)(二)
創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)與策劃設(shè)計(jì),溫縣網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:溫縣等地區(qū)。溫縣做網(wǎng)站價(jià)格咨詢:18982081108
iOS 藍(lán)牙開(kāi)發(fā)(三)
iOS 藍(lán)牙開(kāi)發(fā)(四)
在iOS中藍(lán)牙相關(guān)實(shí)現(xiàn)都是在CoreBluetooth這個(gè)framework中的,所以我們創(chuàng)建一個(gè)單例類中需要先導(dǎo)入 #import CoreBluetooth/CoreBluetooth.h ,再后即可使用這個(gè)單例類進(jìn)行管理我們藍(lán)牙的掃描、連接、狀態(tài)等實(shí)現(xiàn)。
當(dāng) central.state 為CBManagerStatePoweredOn即可開(kāi)始掃描, 具體方法 [self.centralManager scanForPeripheralsWithServices:nil options:nil] 當(dāng)調(diào)用 scanForPeripheralsWithServices:options: 函數(shù)時(shí)就會(huì)實(shí)時(shí)調(diào)用其代理方法 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
peripheral 是外設(shè)類 advertisementData 是廣播的值,一般攜帶設(shè)備名, serviceUUID 等信息。 RSSI 絕對(duì)值越大,表示信號(hào)越差,設(shè)備離的越遠(yuǎn)。如果想裝換成百分比強(qiáng)度, (RSSI+100)/1001 (這是一個(gè)約數(shù),藍(lán)牙信號(hào)值并不一定是-100 - 0的值)
藍(lán)牙的連接是當(dāng)中心設(shè)備掃描到可用外設(shè)后, 利用函數(shù) [self.centralManager connectPeripheral:peripheral options:nil]; 進(jìn)行鏈接, 當(dāng)函數(shù)被調(diào)用后, 就會(huì)回調(diào)其對(duì)應(yīng)的代理函數(shù)。
本篇筆記主要是記錄如何初始化藍(lán)牙的 CBCentralManager 的中心管理類,并記錄如何實(shí)現(xiàn)掃描周邊外設(shè)、如何鏈接、獲取藍(lán)牙當(dāng)前狀態(tài)。
總結(jié)一下藍(lán)牙開(kāi)發(fā)相關(guān)的知識(shí)點(diǎn)和注意事項(xiàng),做個(gè)筆記,也希望你們能少踩坑
(公司部分藍(lán)牙項(xiàng)目為混編項(xiàng)目,藍(lán)牙相關(guān)處理均采用了Objective-C,故本文????均采用OC,Swift處理相同)
藍(lán)牙4.0包含兩個(gè)藍(lán)牙標(biāo)準(zhǔn),它是一個(gè)是 雙模 的標(biāo)準(zhǔn),它包含 傳統(tǒng)藍(lán)牙部分(也稱經(jīng)典藍(lán)牙) 和 低功耗藍(lán)牙部分(BLE) , 二者適用于不同的應(yīng)用場(chǎng)景和應(yīng)用條件。他們的特點(diǎn)如下
所以藍(lán)牙4.0是集成了傳統(tǒng)藍(lán)牙和低功耗藍(lán)牙兩個(gè)標(biāo)準(zhǔn)的,并不只是低功耗藍(lán)牙
藍(lán)牙4.0支持兩種部署方式: 雙模式 和 單模式 ,雙模同時(shí)支持經(jīng)典藍(lán)牙和低功耗藍(lán)牙,而單模則只支持其中一種。
二者更多細(xì)節(jié)詳見(jiàn): 傳統(tǒng)藍(lán)牙和低功耗藍(lán)牙的區(qū)別
iOS中藍(lán)牙相關(guān)功能都封裝進(jìn)了 CoreBluetooth 類中,其中有幾個(gè)常見(jiàn)的參數(shù)和概念
具體API參考 CoreBluetooth藍(lán)牙開(kāi)發(fā)
保存到數(shù)組中的設(shè)備可通過(guò) UUID 來(lái)進(jìn)行區(qū)分。從 iOS7之后蘋果不提供外設(shè)的mac地址,外設(shè)的唯一標(biāo)識(shí)換成了由mac封裝加密后的UUID,需要注意的是不同的手機(jī)獲取同一個(gè)外設(shè)的UUID是不同的,所以在不同手機(jī)之間UUID不是唯一的,但在本機(jī)上可以作為唯一標(biāo)識(shí)(特殊情況手機(jī)刷機(jī)后也會(huì)改變UUID)。
如何獲取Mac地址
一般使用場(chǎng)景是根據(jù)Mac地址區(qū)分某個(gè)外設(shè)
注意點(diǎn):
寫入數(shù)據(jù)時(shí)可能會(huì)遇到需要分包發(fā)送的情況,我們可以通過(guò)下面的API或許當(dāng)前特征支持的最大的單條寫入長(zhǎng)度
maxLength 一般取決于藍(lán)牙模塊內(nèi)部接收 緩沖區(qū) 的大小,很多硬件設(shè)備這個(gè)緩沖區(qū)的大小是 20 字節(jié), 這個(gè)大小也和特征的寫入權(quán)限有關(guān),像具有寫入權(quán)限 withResponse 類的特征其大小一般為 512 字節(jié),當(dāng)然這些都是取決于設(shè)備測(cè)的設(shè)置;
當(dāng)我們單次發(fā)送的數(shù)據(jù)字節(jié)長(zhǎng)度大于 maxLength 時(shí),我們就需要采用分包的方式來(lái)發(fā)送數(shù)據(jù)了,
分包發(fā)送的邏輯類似于下面
這邊延時(shí)主要是設(shè)備側(cè)的接收模塊接收數(shù)據(jù)以及處理能力有限
外圍設(shè)備測(cè)和中心設(shè)備(大部分情況下是手機(jī))保持藍(lán)牙連接的狀態(tài)下,如果長(zhǎng)時(shí)間不產(chǎn)生交互,藍(lán)牙就會(huì)斷開(kāi),所以為了保持兩者持續(xù)的連接狀態(tài),需要做?;钐幚?,也就是需要持續(xù)的發(fā)送心跳包(watchdog)。相應(yīng)的處理是使用一個(gè)定時(shí)器定時(shí)向設(shè)備側(cè)發(fā)送符合設(shè)備協(xié)議格式的心跳包。
斷開(kāi)連接很簡(jiǎn)單,只需要調(diào)用 [self.centralManager cancelPeripheralConnection:peripheral] 傳入需要斷開(kāi)連接的設(shè)備對(duì)象就行了。斷開(kāi)連接時(shí)會(huì)自動(dòng)調(diào)用 centralManager:didDisconnectPeripheral:error: 代理方法。
按照之前的慣例,當(dāng)error為nil時(shí)表示斷開(kāi)成功,error不為nil時(shí)斷開(kāi)失敗。這種理解是錯(cuò)誤的。
當(dāng)你調(diào)用 cancelPeripheralConnection: 方法(主動(dòng)斷開(kāi))斷開(kāi)連接時(shí)error為nil ; 沒(méi)有調(diào)用這個(gè)方法(異常斷開(kāi))而斷開(kāi)時(shí)error返回的是異常斷開(kāi)的原因。也可以理解為主動(dòng)調(diào)用斷開(kāi)連接方法一定會(huì)斷開(kāi)
接下來(lái)就是斷開(kāi)重連的問(wèn)題了,對(duì)藍(lán)牙功能進(jìn)行封裝時(shí)肯定少不了斷開(kāi)重連。首先斷開(kāi)時(shí)可通過(guò)上面的代理方法的error是否為nil判斷是否是異常斷開(kāi),一般情況下異常斷開(kāi)時(shí)是需要重連的
原因就是當(dāng)設(shè)備斷開(kāi)連接后 peripheral.services 為nil了,當(dāng)然 service.characteristics 也是nil,所以需要在斷開(kāi)連接時(shí)把保存這個(gè)設(shè)備對(duì)應(yīng)的服務(wù)和特征全部清除,然后在連接成功時(shí)重新過(guò)一遍發(fā)現(xiàn)服務(wù)和發(fā)現(xiàn)特征的流程就好了。
iOS7 開(kāi)始,Apple加入了Beacon圍欄檢測(cè)的API, ( iBeacon-維基百科 ), 其工作方式是,配備有低功耗藍(lán)牙(BLE)通信功能的設(shè)備使用 BLE 技術(shù)向周圍發(fā)送自己特有的 ID,接收到該 ID 的應(yīng)用軟件會(huì)根據(jù)該 ID 采取一些行動(dòng)。比如,在店鋪里設(shè)置 iBeacon 通信模塊的話,便可讓 iPhone 和 iPad 上運(yùn)行一資訊告知服務(wù)器,或者由服務(wù)器向顧客發(fā)送折扣券及進(jìn)店積分, 或者公司的手機(jī)打卡,只要手機(jī)靠近打卡器一定范圍,手機(jī)測(cè)就向打開(kāi)器發(fā)送打卡信息,從而自動(dòng)打卡。這種場(chǎng)景還有很多。 其中一個(gè)最重要的功能就是App的喚醒功能(殺死后也能喚醒)
舉一個(gè)我們的例子,我們的產(chǎn)品業(yè)務(wù)場(chǎng)景就是在進(jìn)入車輛以后,需要使用藍(lán)牙連接我們的后裝車載設(shè)備以采集車輛信息和駕駛行為行程等,這里有一個(gè)問(wèn)題就是在App被殺死的情況下如何喚醒App, 因?yàn)椴豢赡芤笥脩裘看味贾鲃?dòng)去打開(kāi)App,這樣體驗(yàn)太差。我們的做法是通過(guò)iBeacon,當(dāng)我們的車輛點(diǎn)火以后,設(shè)備測(cè)通電,發(fā)出 iBeacon廣播 ,App實(shí)現(xiàn)監(jiān)聽(tīng)iBeacon相關(guān)功能后就可以喚醒我們App,然后在相應(yīng)的回調(diào)的處理一些事情,比如通過(guò)藍(lán)牙連接設(shè)備。這里的前提條件是我們的硬件設(shè)備測(cè)包含iBeacon模塊,具有iBeacon功能,而且對(duì)iBeacon的廣播頻率也有一定的要求,長(zhǎng)了可能喚醒的功能會(huì)不穩(wěn)定,官方建議的好像是100ms,頻率超高越耗電,但可以讓手機(jī)或其它監(jiān)聽(tīng)設(shè)備越快地發(fā)現(xiàn)iBeacon。標(biāo)準(zhǔn)的BLE廣播距離是100m,這使Beacon在室內(nèi)位置跟蹤場(chǎng)景下的效果更理想。
關(guān)于iBeacon更多的使用及介紹請(qǐng)參考
蘋果核 - iOS端近場(chǎng)圍欄檢測(cè)(一) ——iBeacon
iBeacon技術(shù)初探
上一篇 主要介紹了部分ESC/POS指令集,包括一些常用的排版指令,打印位圖指令等。另外,還介紹了將圖片轉(zhuǎn)換成點(diǎn)陣圖的方法。在這篇文章中,將主要介紹通過(guò)藍(lán)牙和Socket連接打印機(jī),發(fā)送打印指令相關(guān)知識(shí)。這里將用到 CoreBluetooth.framework 和 CocoaAsyncSocket 。
藍(lán)牙是一種支持設(shè)備間短距離通訊的無(wú)線電技術(shù)。iOS系統(tǒng)中,有四個(gè)框架支持藍(lán)牙鏈接:
CoreBluetooth框架有兩個(gè)核心概念,central(中心)和 peripheral(外設(shè)),它們分別有自己對(duì)應(yīng)的API;這里顯然是手機(jī)作為central,藍(lán)牙打印機(jī)作為peripheral;
設(shè)置代理后,會(huì)回調(diào)此方法,確認(rèn)藍(lán)牙狀態(tài),當(dāng)狀態(tài)為 CBCentralManagerStatePoweredOn 才能去掃描設(shè)備,藍(lán)牙狀態(tài)變化時(shí),也會(huì)回調(diào)此方法
調(diào)用此方法開(kāi)始掃描外設(shè)
注意:第一個(gè)參數(shù)指定一個(gè) CBUUID 對(duì)象數(shù)組,每個(gè)對(duì)象表示外圍設(shè)備正在通告的服務(wù)的通用唯一標(biāo)識(shí)符(UUID)。此時(shí),僅返回公布這些服務(wù)的外設(shè)。當(dāng)參數(shù)為 nil ,則返回所有已發(fā)現(xiàn)的外設(shè),而不管其支持的服務(wù)是什么。
當(dāng)掃描到4.0外設(shè)后會(huì)回調(diào)此方法,這里包含設(shè)備的相關(guān)信息,如名稱、UUID、信號(hào)強(qiáng)度等;
調(diào)用此方法連接外設(shè)
[self.centralManager connectPeripheral:peripheral options:nil];
注意:第一個(gè)參數(shù)是要連接的外設(shè)。第二個(gè)參數(shù) options 是可選的 NSDictionary ,系統(tǒng)定義了一下三個(gè)鍵,它們的值都是NSNumber (Boolean);默認(rèn)為NO。當(dāng)設(shè)置為YES,則應(yīng)用進(jìn)入后臺(tái)或者被掛起后,系統(tǒng)會(huì)用Alert通知藍(lán)牙外設(shè)的狀態(tài)變化,效果是這樣
連接成功或失敗,都有對(duì)應(yīng)的回調(diào)方法
連接成功后設(shè)置代理 peripheral.delegate = self ,調(diào)用 [peripheral discoverServices:nil]; 尋找外設(shè)內(nèi)的服務(wù)。這里的參數(shù)是一個(gè)存放 CBUUID 對(duì)象的數(shù)組,用于發(fā)現(xiàn)特定的服務(wù)。當(dāng)傳nil時(shí),表示發(fā)現(xiàn)外設(shè)內(nèi)所有的服務(wù)。發(fā)現(xiàn)服務(wù)后系統(tǒng)會(huì)回調(diào)下面的方法:
發(fā)現(xiàn)服務(wù)后,調(diào)用 [peripheral discoverCharacteristics:nil forService:service]; 去發(fā)現(xiàn)服務(wù)中包含的特征。和上面幾個(gè)方法一樣,第一個(gè)參數(shù)用于發(fā)現(xiàn)指定的特征。為nil時(shí),表示發(fā)現(xiàn)服務(wù)的所有特征。
當(dāng)掃描到寫入特征時(shí),保存,用于寫入數(shù)據(jù)。
寫入數(shù)據(jù),我們只需要調(diào)用方法
這里的 self.peripheral 就是連接的外設(shè), self.characteristicInfo 就是之前保存的寫入特征;這里最好使用 CBCharacteristicPropertyWrite 特征,并且 type 選擇 CBCharacteristicWriteWithResponse 。當(dāng)寫入數(shù)據(jù)成功后,系統(tǒng)會(huì)通過(guò)下面這個(gè)方法通知我們:
由于藍(lán)牙設(shè)備每次可寫入的數(shù)據(jù)量是有限制的,因此,我們需要將之前拼接的打印數(shù)據(jù)進(jìn)行拆分,分批發(fā)送給打印機(jī)
這里的 MAX_CHARACTERISTIC_VALUE_SIZE 是個(gè)宏定義,表示每次發(fā)送的數(shù)據(jù)長(zhǎng)度,經(jīng)筆者測(cè)試,當(dāng) MAX_CHARACTERISTIC_VALUE_SIZE = 20 時(shí),打印文字是正常速度。但打印圖片的速度非常慢, 應(yīng)該在硬件允許的范圍內(nèi),每次發(fā)盡量多的數(shù)據(jù)。 不同品牌型號(hào)的打印機(jī),這個(gè)參數(shù)是不同的,筆者的藍(lán)牙打印機(jī)該值最多到140。超出后會(huì)出現(xiàn)無(wú)法打印問(wèn)題。 最后筆者將該值定為 MAX_CHARACTERISTIC_VALUE_SIZE = 120 ,測(cè)試了公司幾臺(tái)打印機(jī)都沒(méi)有問(wèn)題。
另外iOS9以后增加了方法 maximumWriteValueLengthForType: 可以獲取寫入特診的最大寫入數(shù)據(jù)量,但經(jīng)筆者測(cè)試,對(duì)于部分打印機(jī)(比如我們公司的)是不準(zhǔn)確的,因此,不要太依賴此方法,最好還是自己取一個(gè)合適的值。
注意:每個(gè)打印機(jī)都有一個(gè)緩沖區(qū),緩沖區(qū)的大小視品牌型號(hào)有所不同。打印機(jī)的打印速度有限,如果我們瞬間發(fā)送大量的數(shù)據(jù)給打印機(jī),會(huì)造成打印機(jī)緩沖區(qū)滿。緩沖區(qū)滿后,如繼續(xù)寫入,可能會(huì)出現(xiàn)數(shù)據(jù)丟失,打印亂碼。
這里使用 CocoaAsyncSocket 開(kāi)源框架,與打印機(jī)進(jìn)行 Socket 連接。 CocoaAsyncSocket 中主要包含兩個(gè)類:
這里我們只用到 GCDAsyncSocket ,因此只需要將 GCDAsyncSocket.h 和 GCDAsyncSocket.m 兩個(gè)文件導(dǎo)入項(xiàng)目。
注意:手機(jī)和打印機(jī)必須在同一局域網(wǎng)下,設(shè)置到打印機(jī)的host和port。
連接成功后會(huì)通過(guò)代理回調(diào)
Timeout為負(fù),表示不設(shè)置超時(shí)時(shí)間。這里的data就是 上一篇 中拼接的打印數(shù)據(jù)。
寫入完成后回調(diào)
斷開(kāi)連接有以下幾種方法
連接斷開(kāi)后回調(diào)
讀取到數(shù)據(jù)會(huì)回調(diào)
網(wǎng)口打印機(jī)一般都支持狀態(tài)查詢,查詢指令如下:
可以通過(guò) 上一篇 介紹指令拼接方法,查詢打印機(jī)的狀態(tài)。
本篇只是簡(jiǎn)單介紹了,通過(guò)藍(lán)牙和Socket連接打印機(jī)的方法。雖然可以初步完成連接和打印,但是,在真正的項(xiàng)目中使用還是遠(yuǎn)遠(yuǎn)不夠的。這里還有很多情況需要考慮,比如連接斷開(kāi)、打印機(jī)異常、打印機(jī)緩沖區(qū)滿、打印機(jī)缺紙等。我們可以針對(duì)自身的業(yè)務(wù)情況,進(jìn)行相應(yīng)的處理。
Core Bluetooth Programming Guide
Getting the pixel data from a CGImage object
Core Bluetooth Programming Guide
在iOS應(yīng)用開(kāi)發(fā)中,藍(lán)牙開(kāi)發(fā)是一個(gè)重點(diǎn), 是iOS開(kāi)發(fā)人員必須掌握的一個(gè)知識(shí)。今天小編就將為大家分享一篇iOS大牛寫的有關(guān)藍(lán)牙開(kāi)發(fā)中,使用app發(fā)布一個(gè)peripheral,給其他的central連接的實(shí)現(xiàn)方法。
上面這張圖是什么意思呢,相信開(kāi)發(fā)過(guò)藍(lán)牙項(xiàng)目的童鞋應(yīng)該都清楚,central模式用的都是左邊的類,而peripheral模式用的是右邊的類。
peripheral模式的流程
1. 打開(kāi)peripheralManager,設(shè)置peripheralManager的委托
2. 創(chuàng)建characteristics,characteristics的description 創(chuàng)建service,把characteristics添加到service中,再把service添加到peripheralManager中
3. 開(kāi)啟廣播advertising
4. 對(duì)central的操作進(jìn)行響應(yīng)
- 4.1 讀characteristics請(qǐng)求
- 4.2 寫characteristics請(qǐng)求
- 4.4 訂閱和取消訂閱characteristics
準(zhǔn)備開(kāi)發(fā)環(huán)境
1 、Xcode
2、 開(kāi)發(fā)證書和手機(jī)(藍(lán)牙程序需要使用使用真機(jī)調(diào)試,使用模擬器也可以調(diào)試,但是方法很負(fù)責(zé),本篇分享不做過(guò)多贅述),如果不行可以使用osx程序調(diào)試
3、 藍(lán)牙外設(shè)
實(shí)現(xiàn)步驟
1. 打開(kāi)peripheralManager,設(shè)置peripheralManager的委托。設(shè)置當(dāng)前ViewController實(shí)現(xiàn)CBPeripheralManagerDelegate委托
@interface BePeripheralViewController :UIViewController
初始化peripheralManager
/*
和CBCentralManager類似,藍(lán)牙設(shè)備打開(kāi)需要一定時(shí)間,打開(kāi)成功后會(huì)進(jìn)入委托方法
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
模擬器永遠(yuǎn)也不會(huì)得CBPeripheralManagerStatePoweredOn狀態(tài)
*/
peripheralManager = [[CBPeripheralManageralloc]initWithDelegate:self queue:nil];
2. 創(chuàng)建characteristics,characteristics的description ,創(chuàng)建service,把characteristics添加到service中,再把service添加到peripheralManager中
在委托方法 -(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral中,當(dāng)peripheral成功打開(kāi)后,才可以配置service和characteristics。 這里創(chuàng)建的service和chara對(duì)象是CBMutableCharacteristic和CBMutableService。他們的區(qū)別就像NSArray和NSMutableArray區(qū)別類似。 我們先創(chuàng)建characteristics和description,description是characteristics的描述,描述分很多種, 這里不細(xì)說(shuō)了,常用的就是CBUUIDCharacteristicUserDescriptionString。
//peripheralManager狀態(tài)改變
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
switch (peripheral.state) {
//在這里判斷藍(lán)牙設(shè)別的狀態(tài) 當(dāng)開(kāi)啟了則可調(diào)用 setUp方法(自定義)
case CBPeripheralManagerStatePoweredOn:
NSLog(@"powered on");
[info setText:[NSStringstringWithFormat:@"設(shè)備名%@已經(jīng)打開(kāi),可以使用center進(jìn)行連接",LocalNameKey]];
[self setUp];
break;
caseCBPeripheralManagerStatePoweredOff:
NSLog(@"powered off");
[info setText:@"poweredoff"];
break;
default:
break;
}
}
//配置bluetooch的
-(void)setUp{
//characteristics字段描述
CBUUID*CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUIDUUIDWithString:CBUUIDCharacteristicUserDescriptionString];
/*
可以通知的Characteristic
properties:CBCharacteristicPropertyNotify
permissions CBAttributePermissionsReadable
*/
CBMutableCharacteristic*notiyCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUIDUUIDWithString:notiyCharacteristicUUID]properties:CBCharacteristicPropertyNotify value:nilpermissions:CBAttributePermissionsReadable];
/*
可讀寫的characteristics
properties:CBCharacteristicPropertyWrite |CBCharacteristicPropertyRead
permissionsCBAttributePermissionsReadable | CBAttributePermissionsWriteable
*/
CBMutableCharacteristic*readwriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUIDUUIDWithString:readwriteCharacteristicUUID]properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyReadvalue:nil permissions:CBAttributePermissionsReadable |CBAttributePermissionsWriteable];
//設(shè)置description
CBMutableDescriptor*readwriteCharacteristicDescription1 = [[CBMutableDescriptoralloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:@"name"];
[readwriteCharacteristicsetDescriptors:@[readwriteCharacteristicDescription1]];
/*
只讀的Characteristic
properties:CBCharacteristicPropertyRead
permissionsCBAttributePermissionsReadable
*/
CBMutableCharacteristic *readCharacteristic= [[CBMutableCharacteristic alloc]initWithType:[CBUUIDUUIDWithString:readCharacteristicUUID] properties:CBCharacteristicPropertyReadvalue:nil permissions:CBAttributePermissionsReadable];
//service1初始化并加入兩個(gè)characteristics
CBMutableService *service1 =[[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID1]primary:YES];
[service1setCharacteristics:@[notiyCharacteristic,readwriteCharacteristic]];
//service2初始化并加入一個(gè)characteristics
CBMutableService *service2 =[[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID2]primary:YES];
[service2setCharacteristics:@[readCharacteristic]];
//添加后就會(huì)調(diào)用代理的- (void)peripheralManager:(CBPeripheralManager *)peripheraldidAddService:(CBService *)service error:(NSError *)error
[peripheralManageraddService:service1];
[peripheralManageraddService:service2];
}
3. 開(kāi)啟廣播advertising
//perihpheral添加了service
-(void)peripheralManager:(CBPeripheralManager *)peripheraldidAddService:(CBService *)service error:(NSError *)error{
if (error == nil) {
serviceNum++;
}
//因?yàn)槲覀兲砑恿?個(gè)服務(wù),所以想兩次都添加完成后才去發(fā)送廣播
if (serviceNum==2) {
//添加服務(wù)后可以在此向外界發(fā)出通告調(diào)用完這個(gè)方法后會(huì)調(diào)用代理的
//(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager*)peripheral error:(NSError *)error
[peripheralManager startAdvertising:@{
CBAdvertisementDataServiceUUIDsKey : @[[CBUUIDUUIDWithString:ServiceUUID1],[CBUUID UUIDWithString:ServiceUUID2]],
CBAdvertisementDataLocalNameKey : LocalNameKey
}
];
}
}
//peripheral開(kāi)始發(fā)送advertising
-(void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheralerror:(NSError *)error{
NSLog(@"inperipheralManagerDidStartAdvertisiong");
}
4. 對(duì)central的操作進(jìn)行響應(yīng)
- 4.1 讀characteristics請(qǐng)求
- 4.2 寫characteristics請(qǐng)求
- 4.3 訂閱和取消訂閱characteristics
//訂閱characteristics
-(void)peripheralManager:(CBPeripheralManager*)peripheral central:(CBCentral *)centraldidSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
NSLog(@"訂閱了 %@的數(shù)據(jù)",characteristic.UUID);
//每秒執(zhí)行一次給主設(shè)備發(fā)送一個(gè)當(dāng)前時(shí)間的秒數(shù)
timer = [NSTimer scheduledTimerWithTimeInterval:1target:self selector:@selector(sendData:) userInfo:characteristic repeats:YES];
}
//取消訂閱characteristics
-(void)peripheralManager:(CBPeripheralManager*)peripheral central:(CBCentral *)centraldidUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
NSLog(@"取消訂閱 %@的數(shù)據(jù)",characteristic.UUID);
//取消回應(yīng)
[timer invalidate];
}
//發(fā)送數(shù)據(jù),發(fā)送當(dāng)前時(shí)間的秒數(shù)
-(BOOL)sendData:(NSTimer*)t {
CBMutableCharacteristic *characteristic =t.userInfo;
NSDateFormatter *dft = [[NSDateFormatteralloc]init];
[dft setDateFormat:@"ss"];
NSLog(@"%@",[dftstringFromDate:[NSDate date]]);
//執(zhí)行回應(yīng)Central通知數(shù)據(jù)
return [peripheralManager updateValue:[[dft stringFromDate:[NSDate date]]dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:(CBMutableCharacteristic*)characteristic onSubscribedCentrals:nil];
}
//讀characteristics請(qǐng)求
-(void)peripheralManager:(CBPeripheralManager *)peripheraldidReceiveReadRequest:(CBATTRequest *)request{
NSLog(@"didReceiveReadRequest");
//判斷是否有讀數(shù)據(jù)的權(quán)限
if (request.characteristic.properties CBCharacteristicPropertyRead) {
NSData *data =request.characteristic.value;
[request setValue:data];
//對(duì)請(qǐng)求作出成功響應(yīng)
[peripheralManagerrespondToRequest:request withResult:CBATTErrorSuccess];
}else{
[peripheralManagerrespondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
//寫characteristics請(qǐng)求
-(void)peripheralManager:(CBPeripheralManager *)peripheraldidReceiveWriteRequests:(NSArray *)requests{
NSLog(@"didReceiveWriteRequests");
CBATTRequest *request = requests[0];
//判斷是否有寫數(shù)據(jù)的權(quán)限
if (request.characteristic.properties CBCharacteristicPropertyWrite) {
//需要轉(zhuǎn)換成CBMutableCharacteristic對(duì)象才能進(jìn)行寫值
CBMutableCharacteristic *c=(CBMutableCharacteristic *)request.characteristic;
c.value = request.value;
[peripheralManagerrespondToRequest:request withResult:CBATTErrorSuccess];
}else{
[peripheralManagerrespondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
以上就是iOS藍(lán)牙開(kāi)發(fā)中,app作為外設(shè)被連接的具體實(shí)現(xiàn)方法,希望對(duì)大家開(kāi)發(fā)這項(xiàng)功能有所幫助吧。
文章題目:ios外設(shè)開(kāi)發(fā),ios開(kāi)發(fā)設(shè)備
網(wǎng)頁(yè)鏈接:http://vcdvsql.cn/article2/dsdgsic.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、靜態(tài)網(wǎng)站、搜索引擎優(yōu)化、標(biāo)簽優(yōu)化、Google、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)