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

GAP(Generic Access Profile):它用來控制設(shè)備連接和廣播民泵,GAP 使你的設(shè)備被其他設(shè)備可見,并決定了你的設(shè)備是否可以或者怎樣與合同設(shè)備進(jìn)行交互鸣驱。
GATT(Generic Attribute Profile):BLE連接都是建立在GATT協(xié)議之上的逝钥。GATT 是一個(gè)在藍(lán)牙連接之上的發(fā)送和接收很短的數(shù)據(jù)段的通用規(guī)范乞旦,這些很短的數(shù)據(jù)段被稱為屬性(Attribute)。
BLE中主要有兩個(gè)角色:外圍設(shè)備(Peripheral)和中心設(shè)備(Central)央勒。一個(gè)中心設(shè)備可以連接多個(gè)外圍設(shè)備咧叭,一個(gè)外圍設(shè)備包含一個(gè)或多個(gè)服務(wù)(services),一個(gè)服務(wù)包含一個(gè)或多個(gè)特征(characteristics)。

1页滚、外圍設(shè)備代碼(CBPeripheralManager)

使用CoreBluetooth庫召边,創(chuàng)建CBPeripheralManager,實(shí)現(xiàn)CBPeripheralManagerDelegate代理

//nil表示在主線程中執(zhí)行裹驰。
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

創(chuàng)建完該對象隧熙,會回調(diào)peripheralManagerDidUpdateState:方法判斷藍(lán)牙狀態(tài),藍(lán)牙可用幻林,給外設(shè)配置服務(wù)和特征

CBMutableCharacteristic *writeReadCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"FF01"] properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsReadEncryptionRequired | CBAttributePermissionsWriteEncryptionRequired];
    CBMutableService *service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"FF66"] primary:YES];
    [service setCharacteristics:@[writeReadCharacteristic]];
    [self.peripheralManager addService:service];

注意CBAttributePermissions

typedef NS_OPTIONS(NSUInteger, CBAttributePermissions) {
    CBAttributePermissionsReadable                  = 0x01,         //可讀
    CBAttributePermissionsWriteable                 = 0x02,         //可寫
    CBAttributePermissionsReadEncryptionRequired    = 0x04,                 //可讀贞盯,需要建立安全連接
    CBAttributePermissionsWriteEncryptionRequired   = 0x08             // //可寫,需要建立安全連接
} NS_ENUM_AVAILABLE(10_9, 6_0);

當(dāng)中心設(shè)備讀寫設(shè)置CBAttributePermissionsReadEncryptionRequired/CBAttributePermissionsWriteEncryptionRequired權(quán)限的Characteristic時(shí)沪饺,會彈出彈框躏敢,請求建立安全連接


image.png

給外設(shè)配置服務(wù)特征后,會調(diào)用peripheralManager:didAddService:error: 服務(wù)特征全部添加完后發(fā)起廣播整葡,如果在廣播時(shí)設(shè)置CBAdvertisementDataServiceUUIDsKey父丰,會把該service廣播出去,中心設(shè)備在掃描時(shí)可根據(jù)該uuid找到該設(shè)備掘宪。外圍設(shè)備靠不斷發(fā)廣播蛾扇,使中心設(shè)備發(fā)現(xiàn)它。

[self.peripheralManager startAdvertising:@{CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:@"0xFF66"]],CBAdvertisementDataLocalNameKey:@"ios設(shè)備"}];

當(dāng)中央端連接上了此設(shè)備并訂閱了特征時(shí)會回調(diào) didSubscribeToCharacteristic:

- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
    [self.peripheralManager updateValue:[@"訂閱特征" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:characteristic onSubscribedCentrals:nil];
}

當(dāng)接收到中央端讀的請求時(shí)會調(diào)用didReceiveReadRequest:

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
    if (request.characteristic.properties & CBCharacteristicPropertyRead) {
        NSData *data = [@"收到讀的請求" dataUsingEncoding:NSUTF8StringEncoding];
        [request setValue:data];
        [self.peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
    } else {
        [self.peripheralManager respondToRequest:request withResult:CBATTErrorReadNotPermitted];
    }
}

2魏滚、中心設(shè)備代碼(CBCentralManager)

創(chuàng)建CBCentralManager對象镀首,實(shí)現(xiàn)CBCentralManagerDelegate代理

   self.manager = [[CBCentralManager alloc]initWithDelegate:self queue:nil];

回調(diào)centralManagerDidUpdateState:代理方法,當(dāng)central.state==CBManagerStatePoweredOn時(shí)鼠次,開啟掃描更哄,設(shè)置serviceUUIDs可掃描特定外設(shè),CBCentralManagerScanOptionAllowDuplicatesKey設(shè)為NO不重復(fù)掃描已發(fā)現(xiàn)設(shè)備腥寇,YES是允許

        [self.manager scanForPeripheralsWithServices:@[[CBUUID UUIDWithString:@"0xFF66"]] options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @NO}];

掃描到設(shè)備會回調(diào)centralManager:didDiscoverPeripheral:advertisementData:RSSI:成翩,RSS絕對值越大,表示信號越差赦役,設(shè)備離的越遠(yuǎn)
關(guān)閉掃描

[self.manager stopScan];

連接設(shè)備

    [self.manager connectPeripheral:periphral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}];
// 連接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    //發(fā)現(xiàn)服務(wù)麻敌,實(shí)現(xiàn)CBPeripheralDelegate代理
    [peripheral discoverServices:nil];
}

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

發(fā)現(xiàn)服務(wù)

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error {
//發(fā)現(xiàn)特征
    for (CBService *tempService in peripheral.services) {
        [peripheral discoverCharacteristics:nil forService:tempService];
    }
}

發(fā)現(xiàn)特征

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{    
    for (CBCharacteristic *characteristic in service.characteristics) {
     //可讀 
        if (characteristic.properties & CBCharacteristicPropertyRead) {
             [peripheral readValueForCharacteristic:characteristic];
        }
//可寫
        if (characteristic.properties & CBCharacteristicPropertyWrite) {
              [peripheral writeValue:[@"xxxx" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
        }
//Notify
        if (characteristic.properties & CBCharacteristicPropertyNotify) {
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        }
//可寫不需要回復(fù)
        if (characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse) {
            [permissStr appendString:@" WriteWithoutResponse"];
        }
//Notify,需要配對
        if (characteristic.properties & CBCharacteristicPropertyNotifyEncryptionRequired) {}
}
//讀數(shù)據(jù)的回調(diào)
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;
//是否寫入成功的回調(diào)
 - (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掂摔,一起剝皮案震驚了整個(gè)濱河市术羔,隨后出現(xiàn)的幾起案子赢赊,更是在濱河造成了極大的恐慌,老刑警劉巖级历,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件释移,死亡現(xiàn)場離奇詭異,居然都是意外死亡寥殖,警方通過查閱死者的電腦和手機(jī)玩讳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嚼贡,“玉大人熏纯,你說我怎么就攤上這事”嗦” “怎么了豆巨?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長掐场。 經(jīng)常有香客問我往扔,道長,這世上最難降的妖魔是什么熊户? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任萍膛,我火速辦了婚禮,結(jié)果婚禮上嚷堡,老公的妹妹穿的比我還像新娘蝗罗。我一直安慰自己,他們只是感情好蝌戒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布串塑。 她就那樣靜靜地躺著,像睡著了一般北苟。 火紅的嫁衣襯著肌膚如雪桩匪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天友鼻,我揣著相機(jī)與錄音傻昙,去河邊找鬼。 笑死彩扔,一個(gè)胖子當(dāng)著我的面吹牛妆档,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虫碉,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼贾惦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纤虽,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤乳绕,失蹤者是張志新(化名)和其女友劉穎绞惦,沒想到半個(gè)月后逼纸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡济蝉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年杰刽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片王滤。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贺嫂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雁乡,到底是詐尸還是另有隱情第喳,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布踱稍,位于F島的核電站曲饱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珠月。R本人自食惡果不足惜扩淀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啤挎。 院中可真熱鬧驻谆,春花似錦、人聲如沸庆聘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伙判。三九已至象对,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澳腹,已是汗流浹背织盼。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酱塔,地道東北人沥邻。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像羊娃,于是被迫代替她去往敵國和親唐全。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

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

  • 藍(lán)牙是一個(gè)標(biāo)準(zhǔn)的無線通訊協(xié)議,具有設(shè)備成本低邮利、傳輸距離近和功耗低等特點(diǎn)弥雹,被廣泛的應(yīng)用在多種場合。藍(lán)牙一般分為傳統(tǒng)藍(lán)...
    飛魚灣閱讀 1,941評論 0 2
  • 藍(lán)牙 藍(lán)牙的波段為2400-2483.5MHz(包括防護(hù)頻帶)延届。這是全球范圍內(nèi)無需取得執(zhí)照(但定不是無管制的)的工...
    蘇永茂閱讀 6,157評論 0 11
  • 安卓4.3(API 18)為BLE的核心功能提供平臺支持和API剪勿,App可以利用它來發(fā)現(xiàn)設(shè)備、查詢服務(wù)和讀寫特性方庭。...
    風(fēng)雨byt閱讀 14,049評論 3 43
  • 這次介紹一下藍(lán)牙協(xié)議棧(BLE)的基礎(chǔ)知識械念,藍(lán)牙協(xié)議棧組成如下圖所示头朱,首先我們說說GAP和GATT 1. G...
    一智半解閱讀 7,399評論 0 3
  • 看到這篇文章寫的非常詳細(xì)Introduction to Bluetooth Low Energy,作為 BLE 的...
    在你左右2018閱讀 2,607評論 1 6