iOS藍(lán)牙開發(fā)(結(jié)合智能硬件)

在現(xiàn)在這份工作之前做了挺長(zhǎng)時(shí)間的“智能門禁”“智能家居”方面的Ios開發(fā)出牧,都是基于sip協(xié)議實(shí)現(xiàn)的手機(jī)與硬件設(shè)備的交互。用到的開源庫(kù)分別是idoubs(doubango)蛾扇、linphone攘烛,相比較而言linphone的通話效果會(huì)好些也更穩(wěn)當(dāng)一些。

在軟硬件結(jié)合的產(chǎn)品中藍(lán)牙開發(fā)是必不可少的屁桑,因?yàn)樗{(lán)牙是一種短距離医寿、高效、無需網(wǎng)絡(luò)的通訊方式蘑斧。Ios藍(lán)牙分為“中心者模式“和”外設(shè)模式“靖秩。前者是將手機(jī)作為藍(lán)牙信號(hào)的接收端,用來連接藍(lán)牙設(shè)備并實(shí)現(xiàn)手機(jī)與外設(shè)間的數(shù)據(jù)傳遞竖瘾。后者是將手機(jī)作為藍(lán)牙信號(hào)的發(fā)射端沟突,無需連接藍(lán)牙設(shè)備而只需通過發(fā)送廣播包的形式將數(shù)據(jù)(加密)廣播出去即可,外設(shè)中的藍(lán)牙模塊在接收到該數(shù)據(jù)后進(jìn)行解密->信息比對(duì)捕传,進(jìn)而進(jìn)行其他操作惠拭。

中心者模式?

這里需要使用到CoreBluetooth.framework中的CBCentralManager、CBPeripheral兩個(gè)類,分別用來連接藍(lán)牙和讀寫藍(lán)牙傳遞的數(shù)據(jù)职辅。

藍(lán)牙連接:

1棒呛、創(chuàng)建藍(lán)牙管理對(duì)象

CBCentralManager *manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil];

opetion: 設(shè)置系統(tǒng)自帶選項(xiàng)

CBCentralManagerOptionShowPowerAlertKey?? 默認(rèn)為NO即若手機(jī)藍(lán)牙未打開則不彈框提示,可設(shè)置為YES CBCentralManagerOptionRestoreIdentifierKey?? app被殺死域携,重新恢復(fù)manager的ID?CBCentralManagerScanOptionAllowDuplicatesKey ? 默認(rèn)為NO簇秒,過濾功能是否啟用,每次尋找都會(huì)合并相同的peripheral秀鞭。如果設(shè)為YES的話每次都能接受到來自peripherals的廣播包數(shù)據(jù)趋观。

CBCentralManagerScanOptionSolicitedServiceUUIDsKey ? 掃描的時(shí)候只會(huì)掃描到包含這些UUID的設(shè)備(數(shù)組)。CBConnectPeripheralOptionNotifyOnConnectionKey ? 默認(rèn)為NO锋边,APP被掛起時(shí)如果已連接到peripheral皱坛,是否要給APP一個(gè)提示框。

CBConnectPeripheralOptionNotifyOnDisconnectionKey 默認(rèn)為NO豆巨,APP被掛起時(shí)剩辟,恰好在這個(gè)時(shí)候斷開連接,要不要給APP一個(gè)斷開提示搀矫。

CBConnectPeripheralOptionNotifyOnNotificationKey 默認(rèn)為NO抹沪,APP被掛起時(shí),是否接受到所有的來自peripheral的包都要彈出提示框瓤球。

2、檢測(cè)手機(jī)藍(lán)牙狀態(tài)并掃描藍(lán)牙設(shè)備

#pragma mark CBCentralManagerDelegate

//上面創(chuàng)建中心管理者后 這里會(huì)自動(dòng)監(jiān)測(cè)藍(lán)牙的使用狀態(tài)

- (void)centralManagerDidUpdateState:(CBCentralManager *)central;

根據(jù)central.state狀態(tài)值判斷:

CBCentralManagerStateUnknown未知狀態(tài)/CBCentralManagerStateResetting復(fù)位/CBCentralManagerStateUnsupported不支持/CBCentralManagerStateUnauthorized未授權(quán)/CBCentralManagerStatePoweredOff未開啟/CBCentralManagerStatePoweredOn已開啟

在藍(lán)牙開啟后執(zhí)行[manager scanForPeripheralsWithServices:nil options:nil];搜索全部藍(lán)牙 或?[manager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"EEFF"]] options:nil];搜索指定UUID的藍(lán)牙敏弃。

3卦羡、連接藍(lán)牙設(shè)備

//發(fā)現(xiàn)外設(shè)

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

{? //接下來在這里根據(jù)獲取的外設(shè)peripheral信息對(duì)搜索到的(符合特定服務(wù))藍(lán)牙做篩選。?

if([peripheral.name isEqualToString:@"TESTNAME"]) {

[self.centralManager connectPeripheral:peripheral options:nil];??? //連接

[self.centralManager stopScan];? }}???????? //停止掃描

4麦到、檢測(cè)與藍(lán)牙設(shè)備的連接狀態(tài)

//中心管理者連接外設(shè)成功

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{

?//到這里上面中心管理者的代理方法就執(zhí)行完了绿饵,并且已經(jīng)連接到了指定的藍(lán)牙設(shè)備,所以下面要設(shè)置_peripheral的代理并開始讀取藍(lán)牙攜帶的數(shù)據(jù)瓶颠。

[peripheral setDelegate:self];

[peripheral discoverServices:nil]; //搜索該藍(lán)牙對(duì)應(yīng)的所有服務(wù)

}

//外設(shè)連接失敗

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{

NSLog(@"%s, line = %d, %@=連接失敗", __FUNCTION__, __LINE__, peripheral.name);

}

//丟失連接- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{

NSLog(@"%s, line = %d, %@=斷開連接", __FUNCTION__, __LINE__, peripheral.name);

[self.centralManager connectPeripheral:peripheral options:nil]; ? ? ? ? ? ? ? //重新連接

}

讀寫藍(lán)牙數(shù)據(jù)

5拟赊、搜索藍(lán)牙特征

//已經(jīng)發(fā)現(xiàn)該藍(lán)牙對(duì)應(yīng)的服務(wù)(根據(jù)藍(lán)牙設(shè)備搜索服務(wù))

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error{

for(CBService *service in _peripheral.services) {

[_peripheral discoverCharacteristics:nil forService:service]; //搜索service服務(wù)對(duì)應(yīng)的特征

}}

6、根據(jù)特征屬性做對(duì)應(yīng)的讀寫操作

//已經(jīng)搜索到服務(wù)對(duì)應(yīng)的特征(根據(jù)服務(wù)搜索特征粹淋,然后判斷特征是否可讀吸祟、可寫,最后根據(jù)特征的讀寫屬性進(jìn)行寫入和讀取操作)

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{

for(CBCharacteristic *characteristic in service.characteristics) {

if((unsigned long)characteristic.properties == 10) { //支持讀寫的屬性對(duì)應(yīng)的特征才能寫入數(shù)據(jù)

[peripheral writeValue:[_inputStr dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse]; //將數(shù)據(jù)寫入指定的特征(即給藍(lán)牙設(shè)備發(fā)送數(shù)據(jù))

}}}

7桃移、檢測(cè)是否讀寫成功

//用于檢測(cè)中心向外設(shè)寫數(shù)據(jù)是否成功

-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{

if (error) {

NSLog(@"寫入藍(lán)牙特征數(shù)據(jù)失敗 = %@",error.userInfo); }

else{

NSLog(@"寫入藍(lán)牙特征數(shù)據(jù)成功"); }?

[peripheral readValueForCharacteristic:characteristic];}

8屋匕、訂閱特征并實(shí)時(shí)更新數(shù)據(jù)

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error;

外設(shè)模式

這里需要用到CoreBluetooth.framework中的CBPeripheralManager類,把手機(jī)作為藍(lán)牙廣播包的發(fā)送者借杰。

1过吻、創(chuàng)建設(shè)備類對(duì)象并檢測(cè)手機(jī)藍(lán)牙狀態(tài)

CBPeripheralManager *manager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue() options:nil];

#pragma mark CBPeripheralMangerDelegate

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;

2、發(fā)廣播包

[manager startAdvertising:@{CBAdvertisementDataLocalNameKey : @"將顯示的藍(lán)牙名稱", CBAdvertisementDataServiceUUIDsKey:@"自定義的UUID"}];

注:startAdvertising這個(gè)方法只允許設(shè)置CBAdvertisementDataLocalNameKey(本地名稱)蔗衡、CBAdvertisementDataServiceUUIDsKey(UUID)兩個(gè)參數(shù)纤虽,其他鍵值key可在“中心模式”下的設(shè)備中查看使用乳绕。 CBAdvertisementDataIsConnectable(外設(shè)的可連接數(shù))這個(gè)參數(shù)是廣播包自帶的默認(rèn)參數(shù)(1->可連接 0->不可連接)。廣播包中能傳輸?shù)臄?shù)據(jù)最多為32個(gè)字節(jié)逼纸。

3刷袍、檢測(cè)手機(jī)廣播是否成功

//手機(jī)已經(jīng)開始廣播廣播

- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(nullable NSError *)error;

下面簡(jiǎn)要說明下我們產(chǎn)品的藍(lán)牙應(yīng)用場(chǎng)景

“中心者模式”:

步驟:開啟藍(lán)牙->搜索固定標(biāo)示的藍(lán)牙設(shè)備->連接藍(lán)牙->向藍(lán)牙模塊寫入加密指令->藍(lán)牙模塊將指令信息輸出到硬件主板->執(zhí)行具體操作

注:為了用戶有更好的使用體驗(yàn),這里的連接藍(lán)牙是自動(dòng)連接即連接時(shí)無需授權(quán)(藍(lán)牙模塊開發(fā)人員處理)樊展,且為了保證藍(lán)牙連接的穩(wěn)定性我們使用的藍(lán)牙最大連接數(shù)為一個(gè)呻纹。

“外設(shè)模式”:

步驟:開啟藍(lán)牙->將帶有固定標(biāo)示的加密數(shù)據(jù)寫入廣播包的CBAdvertisementDataLocalNameKey中->硬件中的藍(lán)牙模塊識(shí)別到該數(shù)據(jù)包并將相關(guān)數(shù)據(jù)輸出到主板->解密數(shù)據(jù)并執(zhí)行相應(yīng)操作

注:這個(gè)方式需要和藍(lán)牙模塊開發(fā)人員、硬件開發(fā)人員共同制定數(shù)據(jù)傳輸協(xié)議

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末专缠,一起剝皮案震驚了整個(gè)濱河市雷酪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涝婉,老刑警劉巖哥力,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異墩弯,居然都是意外死亡吩跋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門渔工,熙熙樓的掌柜王于貴愁眉苦臉地迎上來锌钮,“玉大人,你說我怎么就攤上這事引矩×呵穑” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵旺韭,是天一觀的道長(zhǎng)氛谜。 經(jīng)常有香客問我,道長(zhǎng)区端,這世上最難降的妖魔是什么值漫? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮织盼,結(jié)果婚禮上杨何,老公的妹妹穿的比我還像新娘。我一直安慰自己悔政,他們只是感情好晚吞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谋国,像睡著了一般槽地。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天捌蚊,我揣著相機(jī)與錄音集畅,去河邊找鬼。 笑死缅糟,一個(gè)胖子當(dāng)著我的面吹牛挺智,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播窗宦,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼赦颇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了赴涵?” 一聲冷哼從身側(cè)響起媒怯,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎髓窜,沒想到半個(gè)月后扇苞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寄纵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年鳖敷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片程拭。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡定踱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哺壶,到底是詐尸還是另有隱情屋吨,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布山宾,位于F島的核電站,受9級(jí)特大地震影響鳍徽,放射性物質(zhì)發(fā)生泄漏资锰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一阶祭、第九天 我趴在偏房一處隱蔽的房頂上張望绷杜。 院中可真熱鬧,春花似錦濒募、人聲如沸鞭盟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)齿诉。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粤剧,已是汗流浹背歇竟。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抵恋,地道東北人焕议。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像弧关,于是被迫代替她去往敵國(guó)和親盅安。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容