iOS藍(lán)牙開發(fā)詳解

iOS藍(lán)牙開發(fā)詳解

隨著物聯(lián)網(wǎng)技術(shù)的高速發(fā)展挤牛,藍(lán)牙開發(fā)也越來越火熱莹痢。不論是智能穿戴設(shè)備還是藍(lán)牙家具,車聯(lián)網(wǎng)藍(lán)牙墓赴,都是通過藍(lán)牙協(xié)議來進(jìn)行通信竞膳。廢話不多說了,先向大家簡單的介紹有關(guān)藍(lán)牙開發(fā)的知識诫硕。藍(lán)牙低能耗(BLE)坦辟,以下介紹的都是圍繞iOS的藍(lán)牙(4.0)框架展開的。

藍(lán)牙開發(fā)分為中心管理者者模式和外設(shè)管理者模式:1.常用的(90%)就是使用中心管理者者模式作為開發(fā)章办,就是我們手機(jī)作為中心管理者锉走,掃描、連接藍(lán)牙外設(shè)藕届;2.外設(shè)管理者模式挪蹭,這個基本用到的比較少,我們手機(jī)自己作為外設(shè)翰舌,自己創(chuàng)建服務(wù)和特征嚣潜,然后通過廣播,把自己的信息廣播出去椅贱,其他的設(shè)備可以掃描連接到我們的手機(jī)懂算。

在做藍(lán)牙開發(fā)之前只冻,最好先了解一些概念:

  • 廣播包: (Advertising)廣播包是一個公開的信息,別人不需要連接你的設(shè)備就能讀取到的信息;(iOS端由于蘋果的限制计技,無法獲取設(shè)備的Mac地址喜德,只能讓硬件放于廣播包中。)

  • 外設(shè): (peripheral)一個藍(lán)牙硬件就是一個外設(shè)垮媒,一個外設(shè)下有一個或者多個服務(wù);

peripheral.png
  • 服務(wù): (services)藍(lán)牙外設(shè)對外廣播的必定會有一個服務(wù)舍悯,可能也有多個,服務(wù)下面包含著一些特征值睡雇,服務(wù)可以理解成一個端口;
service.png
  • 特征: (characteristic)特征可以理解成一個HTTP的接口萌衬,一般特征都會有value,也就是特征值它抱。每個特征都有一個或多個權(quán)限秕豫,例如讀、寫观蓄、通知混移。向一個特征寫值可以看做是發(fā)起一個HTTP請求。(和HTTP請求不同的是侮穿,如果你寫入的type和硬件底層的type不配套會寫不進(jìn)去歌径。無論是哪個type,系統(tǒng)都會通過代理回調(diào)告知我們是否寫入亲茅。)因此特征是與外界交互的最小單位;
characteristic.png
  • UUID:可以理解成藍(lán)牙上的唯一標(biāo)識符回铛,為了區(qū)分不同的服務(wù)和特征,我們就用UUID來代表服務(wù)和特征克锣。

藍(lán)牙連接可以大致分為以下幾個步驟:

  1. 建立一個Central Manager實例勺届,實現(xiàn)Central代理協(xié)議進(jìn)行藍(lán)牙管理。
  2. 打開藍(lán)牙娶耍,掃描周圍外設(shè),獲取廣播包數(shù)據(jù)信息饼酿。
  3. 根據(jù)廣播包數(shù)據(jù)連接指定外設(shè)榕酒。(目前我測試一個APP連接7個外設(shè)是沒有問題,但是一個手機(jī)能連接多少個并沒有測試故俐,如果有知道的請告訴我想鹰。)
  4. 獲得外設(shè)的服務(wù)。
  5. 獲得服務(wù)的特征药版。
  6. 從外設(shè)讀數(shù)據(jù)辑舷。
  7. 給外設(shè)發(fā)送數(shù)據(jù)。
#pragma mark - 掃描槽片、連接操作
/**
 開始搜索
*/
- (void)startScan {
    
    [self.manager scanForPeripheralsWithServices:nil options:nil];
}
/**
 開始搜索
*/
- (void)startScanWith:(didDiscoverPeripheral)block {
    
    self.didDiscoverPeripheralBlock = block;
    [self.manager scanForPeripheralsWithServices:nil options:nil];//掃描設(shè)備何缓,可設(shè)置掃描的服務(wù)和選項肢础。不填寫可以加快掃描速度。
}
/**
 連接指定設(shè)備碌廓,可設(shè)置連接選項
*/
- (void)linkWith:(Device *)device options:(nullable NSDictionary<NSString *,id> *)dic handle:(didConnectPeripheral)block {
    
    //防止多次點擊传轰,連接多次,只讓連接一個谷婆,如果做BLE4.0多連接可以取消這個限定
    if (self.linkStatus != BLEManagerUnLinked) {
        
        return;
    }
    self.linkStatus = BLEManagerLinking;
    self.didConnectPeripheralBlock = block;
    //iOS端鏈接外設(shè)只能用掃描到的外設(shè)慨蛙,如果連接的外設(shè)為空會crash。
    if (device.per) {
        
        [self.manager connectPeripheral:device.per options:dic];
    }
    [self performSelector:@selector(linkOuttime) withObject:nil afterDelay:5];//超過五秒則認(rèn)為超時纪挎,取消連接
    self.linkDevice = device;
}

/**
 連接超時
 */
- (void)linkOuttime {
    
    if (self.linkStatus != BLEManagerLinked) {
        
        [self disconnectPeripheral:self.manager peripheral:self.linkDevice.per];
        NSError *error = [NSError errorWithDomain:@"連接超時" code:1 userInfo:nil];
        self.linkStatus = BLEManagerUnLinked;
        self.didConnectPeripheralBlock(NO, error);
    }
}

//斷開連接
- (void)disconnectPeripheral:(CBPeripheral *)peripheral {
    
    //斷開連接 如果外設(shè)為空會crash
    if (peripheral) {
        
        [self.manager cancelPeripheralConnection:peripheral];
    } else {
        
        if (self.didDisconnectPeripheralBlock) {

            self.didDisconnectPeripheralBlock(peripheral, nil);
        }
    }
    
    [self cleanData];
}

- (void)cleanData {
    
    //數(shù)據(jù)回歸初始化狀態(tài)
    self.datas = [NSMutableArray array];
    self.allDevice = [@{} mutableCopy];
    self.linkStatus = BLEManagerUnLinked;
}
#pragma mark - 發(fā)送數(shù)據(jù)
/**
 發(fā)送數(shù)據(jù)

 @param data 數(shù)據(jù)
 @param type 寫入類型
 */
- (void)sendData:(NSData *)data withType:(CBCharacteristicWriteType)type{
    
    //數(shù)據(jù)發(fā)送,發(fā)送的時候,外設(shè)特征值必須存在,發(fā)送的數(shù)據(jù)是NSData類型
    /*
     具體使用哪種類型期贫,詢問硬件工程師或者查看接口文檔
     兩者的區(qū)別在于寫入的通道不同(硬件工程師和我說的),如果type不對應(yīng)則會寫入失敗异袄。
     type:
     type為CBCharacteristicWriteWithResponse類型時通砍,didWriteValueForCharacteristic會返回寫入調(diào)用的結(jié)果,而CBCharacteristicWriteWithoutResponse則不會隙轻。埠帕。
     
     */

    [self.send sendData:data withType:type];
}


/**
 外設(shè)的特征值更新通知
 
 @param peripheral 連接(更新)的外設(shè)
 @param characteristic 連接(更新)的外設(shè)的特征值
 @param error 錯誤信息
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    
    //打印出characteristic的UUID和值
    NSLog(@"characteristic.uuid = %@, value = %@",characteristic.UUID,characteristic.value);
    //!注意,value的類型是NSData玖绿,具體開發(fā)時敛瓷,會根據(jù)外設(shè)協(xié)議制定的方式去解析數(shù)據(jù)
    if ([characteristic.UUID.UUIDString isEqualToString:@"readCharacteristic"]) {
        
        NSData *data = characteristic.value;
        //把讀取到的數(shù)據(jù)回調(diào)出去
        for (getData block in self.getDataBlockArr) {
            
            block(data);
        }
    } else if ([characteristic.UUID.UUIDString isEqual:readCharacteristicUUID]||[characteristic.UUID.UUIDString isEqual:notiyCharacteristicUUID]||[characteristic.UUID.UUIDString isEqual:writeCharacteristicUUID]) {
        
        NSData *data = characteristic.value;
        //把讀取到的數(shù)據(jù)回調(diào)出去
        for (getData block in self.getDataBlockArr) {
            
            block(data);
        }
    }
}

/**
 已經(jīng)寫完數(shù)據(jù)回調(diào)
 
 @param peripheral 連接(寫入)的外設(shè)
 @param characteristic 連接(寫入)的外設(shè)的特征值
 @param error 是否寫入成功,如果error為nil則寫入成功斑匪,否則error會存在
 */
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error {
    
    NSLog(@"didWriteValue error = %@", error);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呐籽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚀瘸,更是在濱河造成了極大的恐慌狡蝶,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贮勃,死亡現(xiàn)場離奇詭異贪惹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寂嘉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門奏瞬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泉孩,你說我怎么就攤上這事硼端。” “怎么了寓搬?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵珍昨,是天一觀的道長。 經(jīng)常有香客問我,道長镣典,這世上最難降的妖魔是什么兔毙? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮骆撇,結(jié)果婚禮上瞒御,老公的妹妹穿的比我還像新娘。我一直安慰自己神郊,他們只是感情好肴裙,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著涌乳,像睡著了一般蜻懦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上夕晓,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天宛乃,我揣著相機(jī)與錄音,去河邊找鬼蒸辆。 笑死征炼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的躬贡。 我是一名探鬼主播谆奥,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拂玻!你這毒婦竟也來了酸些?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤檐蚜,失蹤者是張志新(化名)和其女友劉穎魄懂,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闯第,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡市栗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咳短。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肃廓。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诲泌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铣鹏,我是刑警寧澤敷扫,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響葵第,放射性物質(zhì)發(fā)生泄漏绘迁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一卒密、第九天 我趴在偏房一處隱蔽的房頂上張望缀台。 院中可真熱鬧,春花似錦哮奇、人聲如沸膛腐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哲身。三九已至,卻和暖如春贸伐,著一層夾襖步出監(jiān)牢的瞬間勘天,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工捉邢, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留脯丝,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓伏伐,卻偏偏與公主長得像宠进,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秘案,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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