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

本文主要介紹基于藍(lán)牙4.0的智能硬件開發(fā)。藍(lán)牙4.0主要基于<CoreBluetooth/CoreBluetooth.h>這個(gè)庫文件菌湃,下面將以此介紹每個(gè)類的作用.并提供自己對(duì)這些類封裝问拘,最后附有代碼的連接。
CBCentralManager:負(fù)責(zé)查詢用戶藍(lán)牙的狀態(tài)惧所、掃描周圍可見的外設(shè)骤坐、停止掃描、連接指定的外設(shè)等方法通過該類提供下愈,并且通過代理的形式回調(diào)當(dāng)前藍(lán)牙的狀態(tài);

-(void)centralManagerDidUpdateState:(CBCentralManager *)central {    
}

掃描到的外設(shè)纽绍;

-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {

}

連接指定外設(shè)

[centralManager connectPeripheral:peripheral options:nil];

以及連接外設(shè)的狀態(tài)。

//斷開連接
-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
}
//連接失敗
-(void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
}
//連接成功
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
}

CBCentralManager的掃描和連接通過其.h文件我們都能一目了然看出势似,說一下查詢用戶狀態(tài)這方法拌夏,這個(gè)方法的觸發(fā)時(shí)機(jī)其實(shí)在初始化CBCentralManager的時(shí)候,系統(tǒng)內(nèi)部會(huì)進(jìn)行相應(yīng)Api的調(diào)用履因,我們只要在對(duì)應(yīng)的回調(diào)中監(jiān)聽即可障簿。

[[CBCentralManager alloc] initWithDelegate:self queue:nil];

對(duì)于queue這個(gè)參數(shù)我在最后會(huì)做一些介紹,一般只需要給nil代表所有回調(diào)會(huì)在主線程中栅迄。
對(duì)于作過藍(lán)牙相關(guān)開發(fā)的卷谈,有可能會(huì)對(duì)這一系列類進(jìn)行一些封裝,夠后面使用霞篡,而對(duì)于CBCentralManager以懶加載的形式提供世蔗,這樣容易造成一個(gè)問題--->用戶藍(lán)牙狀態(tài)的查詢加只會(huì)進(jìn)行一次查詢,在切換另一個(gè)業(yè)務(wù)頁面的時(shí)候無法獲取當(dāng)前用戶藍(lán)牙狀態(tài)朗兵,造成用戶體驗(yàn)不佳污淋。下面介紹CBPeripheral
CBPeripheral:一種對(duì)外設(shè)的抽象,一個(gè)CBPeripheral對(duì)應(yīng)一個(gè)外設(shè)余掖,它最重要的兩個(gè)特性是外設(shè)的服務(wù)地址和特性地址寸爆,通過服務(wù)地址我們可以找到特性地址,找到特性地址我們就可以寫數(shù)據(jù)了盐欺。下面來介紹具體流程赁豆。
在何時(shí)查找服務(wù),當(dāng)然是在連接外設(shè)成功的時(shí)候了

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    self.currentperipheral  = peripheral;//保存起來冗美,后面用的到
    [peripheral setDelegate:self];
    [peripheral discoverServices:nil];
}

從方法字面意思我們也可以看出大概delegate用來回調(diào)服務(wù)地址的查找情況魔种,其中的services:是一個(gè)外設(shè)服務(wù)地的數(shù)組,可以傳nil粉洼,則會(huì)查找外設(shè)的所有服務(wù)地址节预。

//發(fā)現(xiàn)的服務(wù)地址
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
}

到了這一步我們就可以比照相應(yīng)硬件的協(xié)議文檔了叶摄,如果協(xié)議文檔中的服務(wù)地址被發(fā)現(xiàn)了,可以繼續(xù)下一步了-->該服務(wù)地址下的特性地址安拟。

-(void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
          for (CBService *service in peripheral.services) {
            if ([service.UUID isEqual:[CBUUID UUIDWithString:addresString]]) {//協(xié)議文檔提供的服務(wù)地址
                [peripheral discoverCharacteristics:nil forService:service];
            } else  continue;
    }
}
//對(duì)應(yīng)服務(wù)地址下的特性值蛤吓,特性值一般包含讀和寫,讀用來接收外設(shè)的信息糠赦,寫:向外設(shè)寫數(shù)據(jù)会傲。
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
        
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:charactDict[BlueCharacteristicRead]]]) {
#ifdef DEBUG
            //NSLog(@"the charact read address:%@",charactDict[BlueCharacteristicRead]);
#endif
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];//接收外設(shè)的數(shù)據(jù)
        }
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:charactDict[BlueCharacteristicWrite]]]) {
           
#ifdef DEBUG
           // NSLog(@"the charact write address:%@",charactDict[BlueCharacteristicWrite]);
#endif
            self.characteristic = characteristic;//把寫的特征值保存起來,用來向外設(shè)寫值拙泽、
        }
    }

}

到這里我們就可以向外設(shè)寫值和接收數(shù)據(jù)了
寫:

[self.currentperipheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithResponse];

通過回調(diào)可知道寫入是否失敗(一般不需要處理)

-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error {
}

外設(shè)發(fā)送的數(shù)據(jù)是通過下面方法來接收

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

iOS藍(lán)牙開發(fā)的大致流程介紹到此了淌山,前面說過centralManager初始化之后還有個(gè)queue參數(shù),該參數(shù)可以的作用就是把上面涉及到的一些回調(diào)都加入到該隊(duì)列中奔滑,加入到該隊(duì)列中好處就是可以控制代碼的執(zhí)行順序艾岂,我們只要把鏈接,掃描等操作也加入到該隊(duì)列朋其,就達(dá)到順序的控制王浴,不過這個(gè)沒很大必要。

下面我給一個(gè)我自己封裝的一個(gè)藍(lán)牙庫梅猿。提供了Mac地址的讀取氓辣,和搜索同一類型的外設(shè),斷開重新連接袱蚓,使用起來不難钞啸。

 [YYBlueManger sharedManger].delegate = self;
 [[YYBlueManger sharedManger] scan];
#pragma mark - YYBlueMangerDelegate

-(void)blueManagerFailedState:(YYBlueManger *)manager statu:(YYBlueManagerState)statu{

  //用戶藍(lán)牙狀態(tài)不正常時(shí)候調(diào)用。
}
-(void)blueManagerblescanBluDevice:(YYBlueManger *)manager andTheDevice:(CBPeripheral *)peripheral {
    
    //NSLog(@"%@",peripheral.name);
    if ([peripheral.name isEqualToString:@"你想連接的外設(shè)名字"]) {
        
        if ([YYBlueManger sharedManger].connectState == YYBlueConnectStateConnected || [YYBlueManger sharedManger].connectState ==YYBlueConnectStateConnecting) {
            
            return;
        }
        [[YYBlueManger sharedManger] connect:peripheral orTheDeviceName:nil];
    }
}

-(NSArray *)blueManagerServerAdrres:(YYBlueManger *)manager peripheral:(CBPeripheral *)peripheral {
    
    return @[@"0xxxx"];
}

-(NSDictionary *)blueManagerCharacteristicsAdrres:(YYBlueManger *)manager peripheral:(CBPeripheral *)peripheral {
    
    return @{BlueCharacteristicWrite:@"0xxxxx",BlueCharacteristicRead:@"0xxxxx"};
}


-(void)blueManagerdidConnectSuccees:(YYBlueManger *)manager peripheral:(CBPeripheral *)peripheral {
    
    NSLog(@"連接成功");
    [[YYBlueManger sharedManger] stop];
}

-(void)blueManagerFailedConnect:(YYBlueManger *)manager peripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    
    NSLog(@"連接失敗");
    [[YYBlueManger sharedManger] scan];
}

-(void)blueManagerCutConnect:(YYBlueManger *)manager peripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    
    NSLog(@"斷開連接");
    [[YYBlueManger sharedManger] scan];
}
 [[YYBlueManger sharedManger] writeDataToDevice:nil writeHandle:nil];

github連接:https://github.com/jsonsnow/CoreBlue.git


好久沒接觸智能硬件了喇潘,這幾天又開始智能硬件的開發(fā)体斩,用自己寫的庫也發(fā)現(xiàn)其中存在幾個(gè)問題

  • 在resetConnect的時(shí)候,發(fā)現(xiàn)維持的connect狀態(tài)混亂颖低,因?yàn)樵谌∠耙粋€(gè)已經(jīng)連接的外設(shè)的時(shí)候會(huì)調(diào)用disConnect方法絮吵,導(dǎo)致connectSate = connectSateCut,此事發(fā)現(xiàn)同名字設(shè)備的時(shí)候,因?yàn)閏onnectSate == connectSateCut,因此會(huì)進(jìn)行連接忱屑,解決方法:增加一個(gè)cancelSate 蹬敲,在disConnect中如果connectSate = cancelSate,則直接返回

  • 增加一個(gè)打斷協(xié)議莺戒,在將要連接外設(shè)的時(shí)候調(diào)用willConntetn方法伴嗡,如果實(shí)現(xiàn)方返回YES,則不進(jìn)行此次連接从铲,主要針對(duì)多設(shè)備綁定而設(shè)計(jì)

  • 取消Mac地址讀取瘪校,以及不把已經(jīng)連接的設(shè)備加入數(shù)據(jù)源中

  • 增加一個(gè)搜索外設(shè)的方法,可以給定 @"xxx1,xxx2",則會(huì)搜索名字為xxx1和xxx2的外設(shè)食店,這個(gè)場(chǎng)景主要是針對(duì)外設(shè)名字不同但是其服務(wù)地址和特許值都相同的情形

目前最新的版本還沒上傳渣淤,如有需要可以留下郵箱

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赏寇,一起剝皮案震驚了整個(gè)濱河市吉嫩,隨后出現(xiàn)的幾起案子价认,更是在濱河造成了極大的恐慌,老刑警劉巖自娩,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件用踩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡忙迁,警方通過查閱死者的電腦和手機(jī)脐彩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姊扔,“玉大人惠奸,你說我怎么就攤上這事∏∩遥” “怎么了佛南?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嵌言。 經(jīng)常有香客問我嗅回,道長,這世上最難降的妖魔是什么摧茴? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任绵载,我火速辦了婚禮,結(jié)果婚禮上苛白,老公的妹妹穿的比我還像新娘娃豹。我一直安慰自己,他們只是感情好购裙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布懂版。 她就那樣靜靜地躺著,像睡著了一般缓窜。 火紅的嫁衣襯著肌膚如雪定续。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天禾锤,我揣著相機(jī)與錄音私股,去河邊找鬼。 笑死恩掷,一個(gè)胖子當(dāng)著我的面吹牛倡鲸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播黄娘,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼峭状,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼克滴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起优床,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤劝赔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后胆敞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體着帽,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年移层,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仍翰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡观话,死狀恐怖予借,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情频蛔,我是刑警寧澤灵迫,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站帽驯,受9級(jí)特大地震影響龟再,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尼变,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一利凑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫌术,春花似錦哀澈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至磷籍,卻和暖如春适荣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背院领。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工弛矛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人比然。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓丈氓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子万俗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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