前言
最近實驗室做了一個IOS設備之間使用藍牙進行數(shù)據(jù)交互的項目诽里。中間遇到了很多坑纫溃,現(xiàn)在大致講解一下藍牙通訊的流程父能。干貨請直接下翻到第四節(jié)臣镣。
iOS藍牙基礎知識
背景
iOS的藍牙不能用來傳輸文件。
iOS與iOS設備之間進行數(shù)據(jù)通信谈山,使用gameKit.framework
iOS與其他非iOS設備進行數(shù)據(jù)通信俄删,使用coreBluetooth.framework
iOS中藍牙的實現(xiàn)方案iOS中提供了4個框架用于實現(xiàn)藍牙連接:
- GameKit.framework
用法簡單只能用于iOS設備之間的連接,多用于游戲(比如五子棋對戰(zhàn))奏路,從iOS7開始過期
- MultipeerConnectivity.framework
只能用于iOS設備之間的連接抗蠢,從iOS7開始引入,主要用于文件共享(僅限于沙盒的文件)
- ExternalAccessory.framework
可用于第三方藍牙設備交互思劳,但是藍牙設備必須經(jīng)過蘋果MFi認證(國內(nèi)較少)
- CoreBluetooth.framework(時下熱門)
可用于第三方藍牙設備交互,必須要支持藍牙4.0硬件至少是4s妨猩,系統(tǒng)至少是iOS6藍牙4.0以低功耗著稱潜叛,一般也叫BLE(BluetoothLowEnergy)目前應用比較多的案例:運動手壞、嵌入式設備、智能家居
CoreBluetooth
什么是CoreBluetooth
The Core Bluetooth framework lets your iOS and Mac apps communicate with Bluetooth low energy devices. For example, your app can discover, explore, and interact with low energy peripheral devices, such as heart rate monitors, digital thermostats, and even other iOS devices.
The framework is an abstraction of the Bluetooth 4.0 specification for use with low energy devices. That said, it hides many of the low-level details of the specification from you, the developer, making it much easier for you to develop apps that interact with Bluetooth low energy devices. Because the framework is based on the specification, some concepts and terminology from the specification have been adopted. This chapter introduces you to the key terms and concepts that you need to know to begin developing great apps using the Core Bluetooth framework.
CoreBluetooth框架就是蘋果公司為我們提供的一個庫威兜,我們可以使用這個庫和其他支持藍牙4.0的設備進行數(shù)據(jù)交互销斟。值得注意的是在IOS10之后的APP中,我們需要在 info.plist
文件中添加NSBluetoothPeripheralUsageDescription字段
否則APP會崩潰
藍牙通訊中的外圍設備和中心設備
通常椒舵,設備之間進行通訊的時候都少不了中心設備和外圍設備蚂踊。一般來說,外圍設備具有一些需要傳遞給中心設備的數(shù)據(jù)笔宿,而中心設備獲取這些數(shù)據(jù)之后犁钟,可以進行相應的數(shù)據(jù)處理。同時泼橘,中心設備處理完數(shù)據(jù)之后涝动,也可以向外圍設備發(fā)送信息。例如炬灭,下圖1-1中外圍設備(心率感應器)將數(shù)據(jù)發(fā)送給IOS或者MAC上的APP中醋粟,即中心設備。
中心設備可以發(fā)現(xiàn)并連接到發(fā)送了廣播的外圍設備
外圍設備向中心設備傳遞數(shù)據(jù)的主要方式是廣播重归。廣播中攜帶的數(shù)據(jù)有限(大致為31字節(jié))米愿,里面包含了外圍設備所想要向中心設備提供的數(shù)據(jù)。例如下圖1-2中鼻吮,一個溫度監(jiān)控儀可能會向外廣播現(xiàn)在房間的溫度育苟,中心設備就能拿到溫度數(shù)據(jù)進行相應的一些操作。所以在BLE技術中狈网,廣播是外圍設備讓其他設備能感知到它的主要方式
外圍設備中的數(shù)據(jù)結構
外圍設備中包含一個或者多個服務或提供關于連接信號強度的一些信息宙搬。服務是一個數(shù)據(jù)集合,它包含完成一個(或多個)設備某些功能或特性的相關行為拓哺。例如勇垛,一個心率感應器的服務可能攜帶從心率傳感器發(fā)送而來的數(shù)據(jù)。服務本身是由特征或服務(即引用其它服務)組成士鸥。特征則為外圍設備的服務提供了更詳細的細節(jié)闲孤。例如,剛剛提到的心率服務中的特性就可能包含心率設備的位置和心率測量數(shù)據(jù)烤礁。圖1-3展示了這個心率感應設備中的結構讼积。
中心設備和外圍設備進行數(shù)據(jù)交互
當中心設備成功連接到一個外圍設備之后,它可以知道外圍設備提供的所以服務和特征(廣播的數(shù)據(jù)可能只包含一部分可用的服務)脚仔。
中心設備可以對外圍設備的服務特征進行讀寫操作從而實現(xiàn)和外圍設備的數(shù)據(jù)交互勤众。例如,一個APP可能會通過溫度感應器獲取房間當前溫度鲤脏,并且通過給溫度感應器傳遞數(shù)據(jù)(像操作空調一樣)改變房間溫度们颜。
中心設備吕朵、外圍設備、外圍設備數(shù)據(jù)的表現(xiàn)形式
本地中心設備對象藍牙數(shù)據(jù)交互方式主要都通過Core Bluetooth
框架進行窥突。
當你使用中心端和 遠程外圍設備 進行交互的時候努溃,你的藍牙交互操作基本都在本地中心端執(zhí)行。除非你需要設置一個遠程外圍設備并且通過它對中心設備作出響應阻问,否則你的大部分藍牙交互操作都在中心端進行梧税。
在本地中心端,一個名叫
CBCentralManager
的對象起著舉足輕重的作用称近。這個類被用來管理發(fā)現(xiàn)或者已經(jīng)連接的遠程外圍設備(通常這些外圍設備都以CBPeripheral
對象為存在方式第队,某種程度上可以說CBPeripheral
就是外圍設備,CBCentralManager
就是中心設備)煌茬,包括掃描斥铺、發(fā)現(xiàn)并且連接到廣播的外圍設備。圖1-4展示了本地中心設備和遠程外圍設備在Core Bluetooth
中的表現(xiàn)形式坛善。
- 遠程外圍設備的數(shù)據(jù)由
CBService
和CBCharacteristic
對象表示> 當你在和遠程外圍設備進行數(shù)據(jù)交互的時候晾蜘,你實際上是在和其服務和特征進行交互。在Core Bluetooth
框架中眠屎,服務由CBService
對象代表剔交。同樣的,特征也由CBCharacteristic
對象代表改衩。圖1-5闡述了外圍設備中的結構信息岖常。
本地外圍設備對象
在IOS6和OS X v10.9之后,Mac和IOS設備都能夠作為 本地外圍設備 給包括Mac葫督、iPhone竭鞍、和iPad的設備分享數(shù)據(jù)。當你實現(xiàn)本地外圍設備角色功能橄镜,在藍牙交互角色中偎快,你就表現(xiàn)為外圍設備。
- 在遠程外圍設備端洽胶,本地外圍設備由
CBPeripheralManager
對象作為代表晒夹。這些對象被用來管理發(fā)布外圍設備服務和特征數(shù)據(jù)并實現(xiàn)對中心設備的廣播。它也用來回應中心設備的讀寫操作姊氓。圖1-6展示了外圍設備在藍牙交互中的角色信息丐怯。
- 本地外圍設備由
CBMutableService
和CBMutableCharacteristic
對象代表> 當你和本地外圍設備進行數(shù)據(jù)處理的時候,你其實是在和服務和特征的可變版本打交道翔横。在Core Bluetooth
框架中读跷,本地外圍設備的服務由CBMutableService
代表。同樣禾唁,本地外圍設備特種由CBMutableCharacteristic
代表舔亭。圖1-7傳輸了本地外圍設備服務和特征的樹狀結構些膨。
藍牙通訊應用實例
對藍牙基礎知識有了一個大致了解之后,我們現(xiàn)在利用CoreBluetooth
框架進行實戰(zhàn)钦铺。我們需要外圍設備和中心設備模式,所以創(chuàng)建兩個分別名為BluetoothCentralTest
和BluetoothPeripheralTest
的項目肢预。 在后期我們需要測試藍牙的時候矛洞,如果只有一個IOS設備,我們可以下載一個名為 LightBlue
的軟件用來模擬另一個藍牙設備
創(chuàng)建外圍設備
- 外圍設備的工作流程為:
1烫映、開啟外圍設備管理
2沼本、設置服務、特征锭沟、描述等信息
3抽兆、開始廣播
外圍設備和中心設備的數(shù)據(jù)交互可以用通知的形式來進行或者通過
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request
和- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests
這兩個方法來進行。 其中通知主要是中心設備訂閱外圍設備族淮,一般用作外圍設備單方面向中心設備發(fā)送數(shù)據(jù)我創(chuàng)建外圍設備是以單例的方式來創(chuàng)建辫红,代碼如下,注意:在.h文件中需要聲明協(xié)議CBPeripheralManagerDelegate
//
//LARPeripheralManager.m
//BlueToothPeripheralTest
//
//Created by柳鈺柯on 2016/12/4.
//Copyright ? 2016年柳鈺柯. All rights reserved.
//
#import"LARPeripheralManager.h"
staticNSString *constServiceUUID1 =@"FFF0";
staticNSString *constnotiyCharacteristicUUID =@"FFF1";
staticNSString *constreadwriteCharacteristicUUID =@"FFF2";
staticNSString *constServiceUUID2 =@"FFE0";
staticNSString *constreadCharacteristicUUID =@"FFE1";
staticNSString *constLocalNameKey =@"iPhone";
@implementationLARPeripheralManager{
//外圍設備管理器
CBPeripheralManager *peripheralManager;
//定時器
NSTimer *timer;
}
+ (instancetype)shareInstance
{
staticLARPeripheralManager *peripheral;
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
peripheral = [[selfalloc] init];
});
returnperipheral;
}
- (instancetype)init
{
if(self= [superinit]) {
NSLog(@"外圍設備單例創(chuàng)建");
peripheralManager = [[CBPeripheralManager alloc]initWithDelegate:selfqueue:nil];
}
returnself;
}
//初始化一些UUID和特征信息,此處設置的一些信息祝辣,在中心設備中可以根據(jù)需要進行過濾
- (void)setUp
{
// characteristic字段描述
CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
/*
可以通知的Characteristic
properties:CBCharacteristicPropertyNotify
permissions: CBAttributePermissionsReadable
*/
CBMutableCharacteristic *notiyCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:notiyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nilpermissions:CBAttributePermissionsReadable];
/*
可讀寫的characteristics
properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead
permissions CBAttributePermissionsReadable | CBAttributePermissionsWriteable
*/
CBMutableCharacteristic *readwriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readwriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nilpermissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
//設置descriptor
CBMutableDescriptor *readwriteCharacteristicDescription1 = [[CBMutableDescriptor alloc]initWithType: CBUUIDCharacteristicUserDescriptionStringUUID value:@"name"];
[readwriteCharacteristic setDescriptors:@[readwriteCharacteristicDescription1]];
/*
只讀的Characteristic
properties:CBCharacteristicPropertyRead
permissions CBAttributePermissionsReadable
*/
CBMutableCharacteristic *readCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readCharacteristicUUID] properties:CBCharacteristicPropertyRead value:nilpermissions:CBAttributePermissionsReadable];
//service1初始化并加入兩個characteristics
CBMutableService *service1 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID1] primary:YES];
[service1 setCharacteristics:@[notiyCharacteristic,readwriteCharacteristic]];
//service2初始化并加入一個characteristics
CBMutableService *service2 = [[CBMutableService alloc]initWithType:[CBUUID UUIDWithString:ServiceUUID2] primary:YES];
[service2 setCharacteristics:@[readCharacteristic]];
//添加后就會調用代理的- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error
[peripheralManager addService:service1];
[peripheralManager addService:service2];
}
#pragma mark - <CBPeripheralManagerDelegate>
//檢測藍牙狀態(tài)變化贴妻,當藍牙狀態(tài)改變時,自動回調
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
switch(peripheral.state) {
//在這里判斷藍牙設別的狀態(tài)當開啟了則可調用setUp方法(自定義)
caseCBManagerStatePoweredOn:
NSLog(@"powered on");
//運行初始化方法
[selfsetUp];
break;
caseCBManagerStatePoweredOff:
NSLog(@"powered off");
break;
default:
break;
}
}
//添加了服務蝙斜,添加服務后需要廣播名惩,一旦廣播,外圍設備就可以被中心設備發(fā)現(xiàn)孕荠,同樣外圍設備所攜帶的數(shù)據(jù)也能被中心設備捕獲
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error
{
if(error) {
NSLog(@"%@",[error localizedDescription]);
return;
}
//添加服務后娩鹉,發(fā)送廣播
//發(fā)送廣播后會自動調用
// - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error
[peripheralManager startAdvertising:@{
CBAdvertisementDataServiceUUIDsKey :@[[CBUUID UUIDWithString:ServiceUUID1],[CBUUID UUIDWithString:ServiceUUID2]],
CBAdvertisementDataLocalNameKey : LocalNameKey
}];
}
//通知發(fā)送了廣播
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error
{
NSLog(@"已經(jīng)開始廣播");
}
//中心設備訂閱特征后會調用這個方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
{
NSLog(@"訂閱了%@的數(shù)據(jù)",characteristic.UUID);
//分配定時任務
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(sendData:)
userInfo:characteristic
repeats:YES];
}
//中心設備取消訂閱特征后調用這個方法
-(void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
NSLog(@"取消訂閱%@的數(shù)據(jù)",characteristic.UUID);
//取消定時器
[timer invalidate];
}
//發(fā)送數(shù)據(jù)
- (void)sendData:(NSTimer *)t{
CBMutableCharacteristic *characteristic = t.userInfo;
if([peripheralManager updateValue:[[NSString stringWithFormat:@"Sending Data"] dataUsingEncoding:NSUTF8StringEncoding]forCharacteristic:characteristic onSubscribedCentrals:nil]) {
NSLog(@"發(fā)送數(shù)據(jù)成功");
}else{
NSLog(@"發(fā)送數(shù)據(jù)錯誤");
}
}
//中心設備讀characteristics請求
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request{
NSLog(@"didReceiveReadRequest");
//判斷是否有讀數(shù)據(jù)的權限
if(request.characteristic.properties & CBCharacteristicPropertyRead) {
//NSData *data = request.characteristic.value;
NSData *data = [[NSString stringWithFormat:@"通過characteristics讀請求"] dataUsingEncoding:NSUTF8StringEncoding];
[request setValue:data];
//對請求作出成功響應
[peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
}else{
[peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
//外圍設備寫characteristics請求
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests{
NSLog(@"didReceiveWriteRequests");
CBATTRequest *request = requests[0];
//判斷是否有寫數(shù)據(jù)的權限
if(request.characteristic.properties & CBCharacteristicPropertyWrite) {
//需要轉換成CBMutableCharacteristic對象才能進行寫值
CBMutableCharacteristic *c =(CBMutableCharacteristic *)request.characteristic;
c.value = request.value;
NSLog(@"收到中心設備發(fā)送信息:%@",[[NSString alloc] initWithData:c.value encoding:NSUTF8StringEncoding]);
[peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
}else{
[peripheralManager respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
}
}
//外圍設備更新描述后調用
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral{
NSLog(@"peripheralManagerIsReadyToUpdateSubscribers");
}
@end
- 我們嘗試用
lighblue
來鏈接一下外圍設備試試,結果如圖
創(chuàng)建中心設備
- 中心設備的工作流程為:
1、創(chuàng)建中心設備
2稚伍、發(fā)現(xiàn)外圍設備
3弯予、鏈接外圍設備
4、發(fā)現(xiàn)服務和特征4.1 獲取服務
4.2 獲取特征值
4.3 獲取特征描述
5槐瑞、 數(shù)據(jù)交互
6熙涤、 訂閱通知
7、 斷開鏈接
中心設備中讀取外圍設備的數(shù)據(jù)可以使用訂閱外圍設備通知或者是調用
[peripheral readValueForCharacteristic:<#(nonnull CBCharacteristic *)#>]
和[peripheral readValueForDescriptor:<#(nonnull CBDescriptor *)#>]
方法來獲取特征或者描述的數(shù)據(jù)困檩,至于需要獲取那一層的祠挫,則需要自己定義。* 我是在特征值這一層通過訂閱外圍設備通知的方式獲取數(shù)據(jù)悼沿,所以需要在- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
掃描到匹配的特征后等舔,進行數(shù)據(jù)訂閱。值得注意的是糟趾,中心設備掃描到外圍設備后慌植,想要保持連接甚牲,需要將外圍設備保留下來〉粒可以使用一個強引用變量引用丈钙,也可以將外圍設備添加到數(shù)組。推薦使用后者
同樣交汤,也需要遵守
CBCentralManagerDelegate
和CBPeripheralDelegate協(xié)議
//
//LARCentralBlueTooth.m
//Unity-iPhone
//
//Created by柳鈺柯on 2016/11/18.
//
//
#import"LARCentralBlueTooth.h"
staticNSString *constServiceUUID1 =@"FFF0";
staticNSString *constnotiyCharacteristicUUID =@"FFF1";
staticNSString *constreadwriteCharacteristicUUID =@"FFF2";
@interfaceLARCentralBlueTooth ()
/**系統(tǒng)藍牙管理對象*/
@property(strong,nonatomic,readwrite) CBCentralManager *manager;
/**掃描到的設備*/
@property(strong,nonatomic,readwrite) NSMutableArray *discoverPeripheral;
/**當前連接設備*/
@property(strong,nonatomic) CBPeripheral *currentPeripheral;
@end
@implementationLARCentralBlueTooth
+ (instancetype)shareInstance{
staticLARCentralBlueTooth *blueTooth;
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
blueTooth = [[selfalloc] init];
});
returnblueTooth;
}
- (instancetype)init
{
if(self= [superinit]){
NSLog(@"單例實例化");
_manager = [[CBCentralManager alloc] initWithDelegate:selfqueue:dispatch_get_global_queue(0,0)];
_discoverPeripheral = [[NSMutableArray alloc] init];
}
returnself;
}
#pragma mark -
//檢查設備藍牙開關的狀態(tài)
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if(central.state == CBManagerStatePoweredOn) {
NSLog(@"藍牙已打開");
//開始掃描設備
//掃描到設備之后會進入
//-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法
[_manager scanForPeripheralsWithServices:niloptions:nil];
}else{
NSLog(@"藍牙已關閉");
}
}
//發(fā)現(xiàn)設備后,根據(jù)過濾設置進行連接
-(void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
NSLog(@"搜索到了設備%@",peripheral.name);
//我的另外一個設備的名字以閆開頭雏赦,可以在這里自行設置過濾
if([peripheral.name hasPrefix:@"閆"]) {
//持有設備
if(![self.discoverPeripheral containsObject:peripheral]) {
//數(shù)組或者變量保留外圍設備二者選其一
//使用數(shù)組保留外圍設備引用
// [self.discoverPeripheral addObject:peripheral];
//使用一個strong變量強引用持有外圍設備
self.currentPeripheral = peripheral;
//連接設備
[_manager connectPeripheral:peripheral options:nil];
NSLog(@"準備連接設備%@",peripheral.name);
}
}
}
#pragma mark -連接狀態(tài)
//連接設備失敗自動調用
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@">>>連接%@失敗>>>錯誤:%@",peripheral.name,[error localizedDescription]);
}
//斷開連接自動調用
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
{
NSLog(@">>>斷開%@連接",peripheral.name);
}
//連接成功自動調用
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@">>>連接%@成功",peripheral.name);
//設置外圍設備代理
[peripheral setDelegate:self];
//開始掃描外圍設備的服務
//掃描到服務會進入
// - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
[peripheral discoverServices:nil];
}
#pragma mark -
//掃描到設備的服務后會進入這個方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
if(error){
NSLog(@"掃描服務錯誤:%@",[error localizedDescription]);
}else{
for(CBService *serverinperipheral.services) {
//掃描服務的特征
//掃描到后會進入
// - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
[peripheral discoverCharacteristics:nilforService:server];
NSLog(@"搜索到了一個服務:%@",server.UUID.UUIDString);
}
}
}
//掃描到服務的特征值
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if(error) {
NSLog(@"掃描服務:%@的特征值錯誤:%@",service.UUID,[error localizedDescription]);
return;
}
//獲取到特征值
for(CBCharacteristic *characteristicinservice.characteristics){
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:notiyCharacteristicUUID]]) {
//訂閱特征值的數(shù)據(jù)
[selfnotifyCharacteristic:peripheral characteristic:characteristic];
//讀取發(fā)送的數(shù)據(jù)
[peripheral readValueForCharacteristic:characteristic];
}
}
}
//當獲取到外圍設備更新的描述信息后(即數(shù)據(jù))會調用此方法
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
if(error)
{
NSLog(@"更新特征值數(shù)據(jù): %@錯誤: %@", characteristic.UUID,[error localizedDescription]);
}
//這里對收到的數(shù)據(jù)進行處理,需要和發(fā)送端一致
if(characteristic.value !=nil) {
NSString *data = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
NSLog(@"收到外圍設備發(fā)送的信息:%@",data);
[peripheral writeValue:[[NSString stringWithFormat:@"get"] dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
//設置通知
- (void)notifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
NSLog(@"訂閱通知成功");
//設置通知
[peripheral setNotifyValue:YESforCharacteristic:characteristic];
}
//取消通知
- (void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
[peripheral setNotifyValue:NOforCharacteristic:characteristic];
}
//停止掃描并斷開連接
-(void)disconnectPeripheral:(CBCentralManager *)centralManager
peripheral:(CBPeripheral *)peripheral{
//停止掃描
[centralManager stopScan];
//斷開連接
[centralManager cancelPeripheralConnection:peripheral];
}
@end
- 測試結果如下圖所示:
結語
- 寫了幾個小時終于寫完了芙扎,覺得不錯的話星岗,請點個贊~
- 這個也是我自己琢磨、學習了幾天之后學會的戒洼,難免有錯誤俏橘,請發(fā)現(xiàn)錯誤后聯(lián)系我,我會及時糾正圈浇。謝謝寥掐!
- 如果有疑問,歡迎留言或者給我發(fā)郵件:449618602@qq.com
- 項目地址:藍牙Demo
- 不要臉的安利一下自己的博客地址,博客搭建好沒多久汉额,后續(xù)會平均一周更新一次:Larry代碼成詩