iOS藍(lán)牙通訊 CoreBluetooth的使用

蘋果的藍(lán)牙通訊使用的是CoreBluetooth.framework,實(shí)際交互是使用的CBCentralManager,搜索鏈接使用的代理是:CBCentralManagerDelegate捻艳,特性的讀取和數(shù)據(jù)交互使用的代理是CBPeripheralDelegate榜轿。本文主要目的是為了對于藍(lán)牙通訊進(jìn)行梳理勃黍。

本文是以CBCentralMannager 中心模式 :以手機(jī)(app)作為中心,連接其他外設(shè)的場景(主要寫此種該模式的應(yīng)用方法)
主要要使用的是CBPeripheral币叹、CBService矢洲、CBCharacteristic
三者的關(guān)系:

關(guān)系圖.png

一個(gè)CBPeripheral有一個(gè)或者多個(gè)CBService,而每一個(gè)CBService有一個(gè)或者多個(gè)CBCharacteristic足陨,通過可寫的CBCharacteristic發(fā)送數(shù)據(jù),而每一個(gè)CBCharacteristic有一個(gè)或者多個(gè)Description用于描述characteristic的信息或?qū)傩?/p>


下面介紹一下使用藍(lán)牙設(shè)備連接的主要步奏
第一步引用頭文件嫂粟、代理和管理器

#import <CoreBluetooth/CoreBluetooth.h>
@interface BluetoochManager()<CBCentralManagerDelegate,CBPeripheralDelegate>{
    CBCentralManager *CBManager;
}

初始化藍(lán)牙設(shè)備代理

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

//代理回調(diào)
#pragma mark CBCentralManagerDelegate
//設(shè)備列表相關(guān)
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    NSString * state = nil;
    
    switch ([central state])
    {
        case CBManagerStateUnsupported:
        {
            state = @"硬件不支持低電量藍(lán)牙";
        }
            break;
        case CBManagerStateUnauthorized:
        {
            state = @"這個(gè)應(yīng)用程序未被授權(quán)使用藍(lán)牙";
            
        }
            break;
        case CBManagerStatePoweredOff:
        {
            state = @"藍(lán)牙處于未開啟,請開啟藍(lán)牙";
            
        }
            break;
        case CBManagerStatePoweredOn:
        {
            state = @"work";
            NSLog(@"藍(lán)牙啟動(dòng)");
            //切記藍(lán)牙啟動(dòng)后才可以調(diào)用相關(guān)搜索設(shè)備的功能
        }
            break;
        default :
        {
            state = @"未知名錯(cuò)誤";
        }
            break;
    }
}

搜索藍(lán)牙設(shè)備

/**
 查找藍(lán)牙設(shè)備
 */
-(void)scanForPeripherals{
    NSDictionary *options   = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
    [[self manager] scanForPeripheralsWithServices:self.scanUUIDS options:options];
}
//代理回調(diào)
#pragma mark CBCentralManagerDelegate
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI{
    NSString *str = [NSString stringWithFormat:@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral.name, RSSI, peripheral.identifier.UUIDString, advertisementData];
    NSLog(@"外設(shè):\n %@",str);
    
}

連接設(shè)備

// 連接某個(gè)設(shè)備
- (void)connectPeripheral:(CBPeripheral*)peripheral{
    
    if ([peripheral state]==CBPeripheralStateDisconnected) {
        [CBManager connectPeripheral:peripheral options:nil];
    }else{
        NSString *state = @"設(shè)備正在使用中";
    }
}
//代理回調(diào)
#pragma mark CBCentralManagerDelegate 連接外設(shè)
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    NSLog(@"連接外設(shè) error:\n %@",error);
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"Did connect to peripheral: %@", peripheral);
    [self stopScanning];
}
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    NSLog(@"Did disconnect to peripheral: %@", peripheral);
}

查找設(shè)備服務(wù)

/**
 發(fā)現(xiàn)某個(gè)藍(lán)牙設(shè)備的服務(wù)
 
 @param peripheral 設(shè)備信息
 */
-(void)discoverServicesAtPeripheral:(CBPeripheral*)peripheral{
    peripheral.delegate = self;
    NSArray     *uuids  = [NSArray new];
    [peripheral discoverServices:uuids];
}
//代理回調(diào)
#pragma mark CBPeripheralDelegate 設(shè)備服務(wù)
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error{
    NSArray     *services   = nil;
    if (error) {
        NSLog(@"設(shè)備的服務(wù)查找 Error %@\n", error);
    }
    services = [peripheral services];
    if (!services || ![services count]) {
        NSString *s_message=@"該設(shè)備沒有服務(wù)";
    }
}

查找服務(wù)的特性

/**
 發(fā)現(xiàn)某個(gè)藍(lán)牙設(shè)備服務(wù)的特性類別
 
 @param peripheral 設(shè)備
 @param aService 服務(wù)
 @param aCallBack 特性列表
 */
-(void)discoverCharacteristicsAtPeripheral:(CBPeripheral*)peripheral ofService:(CBService*)aService{
 
    [peripheral discoverCharacteristics:[NSArray new] forService:aService];
    
}
//代理回調(diào)
#pragma mark CBPeripheralDelegate 服務(wù)的特性
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{
    NSArray *characteristics = [service characteristics];
    if (error) {
        NSLog(@"設(shè)備的服務(wù)的特性查找 Error %@\n", error);
    }
    if (!characteristics||!characteristics.count) {
        NSString *c_message=@"該設(shè)備沒有服務(wù)相關(guān)的特性";
    }
}

讀取墨缘、訂閱星虹、寫入信息

/**
 訂閱某個(gè)藍(lán)牙設(shè)備服務(wù)的特性變化
 
 @param peripheral 設(shè)備
 @param characteristic 特性
 */
-(void)setNotifyValueAtPeripheral:(CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic*)characteristic{
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
}

/**
 讀取設(shè)備服務(wù)的特性里的數(shù)據(jù)
 
 @param peripheral 設(shè)備
 @param characteristic 特性
 */
-(void)readValueAtPeripheral:(CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic *)characteristic{
    [peripheral readValueForCharacteristic:characteristic];
}

/**
 根據(jù)設(shè)備服務(wù)的特性寫入數(shù)據(jù)
 
 @param data 待數(shù)據(jù)
 @param peripheral 設(shè)備
 @param characteristic 特性
 @param aType CBCharacteristicWriteType 類型
 */
-(void)writeValue:(NSData *)data atPeripheral:(CBPeripheral*)peripheral forCharacteristic:(CBCharacteristic *)characteristic type:(CBCharacteristicWriteType)aType {
    [peripheral writeValue:data forCharacteristic:characteristic type:aType];
}

//代理回調(diào)
#pragma mark CBPeripheralDelegate 讀寫回調(diào)
//數(shù)據(jù)更新
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@"數(shù)據(jù)更新失敗了 %@",error);
    }
    NSLog(@"收到的數(shù)據(jù):%@",characteristic);
}
//訂閱特性的狀態(tài)通知
-(void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@"訂閱特性狀態(tài)更新出錯(cuò)了 %@",error);
    }
    NSLog(@"狀態(tài)的數(shù)據(jù):%@",characteristic);
}
//寫入數(shù)據(jù)的狀態(tài)消息
-(void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@"特性寫入出錯(cuò)了 %@",error);
    }
    NSLog(@"寫入的數(shù)據(jù):%@",characteristic);
}

藍(lán)牙工具的源碼地址:Github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市镊讼,隨后出現(xiàn)的幾起案子搁凸,更是在濱河造成了極大的恐慌,老刑警劉巖狠毯,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件护糖,死亡現(xiàn)場離奇詭異,居然都是意外死亡嚼松,警方通過查閱死者的電腦和手機(jī)嫡良,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來献酗,“玉大人寝受,你說我怎么就攤上這事『辟耍” “怎么了很澄?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颜及。 經(jīng)常有香客問我甩苛,道長,這世上最難降的妖魔是什么俏站? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任讯蒲,我火速辦了婚禮,結(jié)果婚禮上肄扎,老公的妹妹穿的比我還像新娘墨林。我一直安慰自己,他們只是感情好犯祠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布旭等。 她就那樣靜靜地躺著,像睡著了一般衡载。 火紅的嫁衣襯著肌膚如雪搔耕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天月劈,我揣著相機(jī)與錄音度迂,去河邊找鬼。 笑死猜揪,一個(gè)胖子當(dāng)著我的面吹牛惭墓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播而姐,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腊凶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拴念?” 一聲冷哼從身側(cè)響起钧萍,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎政鼠,沒想到半個(gè)月后风瘦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡公般,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年万搔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片官帘。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞬雹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刽虹,到底是詐尸還是另有隱情酗捌,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布涌哲,位于F島的核電站胖缤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏阀圾。R本人自食惡果不足惜草姻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稍刀。 院中可真熱鬧撩独,春花似錦、人聲如沸账月。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽局齿。三九已至剧劝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抓歼,已是汗流浹背讥此。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工拢锹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人萄喳。 一個(gè)月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓卒稳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親他巨。 傳聞我的和親對象是個(gè)殘疾皇子充坑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

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