iOS 蓝牙
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 蓝牙相关的知识,希望对你有一定的参考价值。
参考技术A 1. ios中开发蓝牙常用的系统库是<CoreBluetooth/CoreBluetooth.h>。2.蓝牙外设必需为4.0及以上(2.0需要MFI认证),否则无法进行开发,蓝牙4.0设施由于低耗电,所以也叫做BLE。
3. CoreBluetooth框架的核心其实是俩东西
3.1 Peripheral
3.2 Central
4. 服务和特征(service characteristic):简而言之,外部蓝牙中它有若干个服务service(服务你能了解为蓝牙所拥有的可以力),而每个服务service下拥有若干个特征characteristic(特征你能了解为解释这个服务的属性)。
5. Descriptor(形容)使用来形容characteristic变量的属性。例如,一个descriptor能规定一个可读的形容,或者者一个characteristic变量可接受的范围,或者者一个characteristic变量特定的单位。
3.1 创建一个CBCentralManager实例来进行蓝牙管理;
3.2 搜索扫描外围设备;
3.3 连接外围设备;
3.4 获得外围设备的服务;
3.5 获得服务的特征;
3.6 从外围设备读取数据;
3.7 给外围设备发送(写入)数据。
4.1 初始化
dispatch_queue_t centralQueue = dispatch_queue_create(“centralQueue",DISPATCH_QUEUE_SERIAL);
NSDictionary *dic = @CBCentralManagerOptionRestoreIdentifierKey : restoreIdentifier;
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:dic];
CBCentralManagerOptionRestoreIdentifierKey对应的是一个唯一标识的字符串,用于蓝牙进程被杀掉恢复连接时使用
4.2 扫描
/*
*扫描设备
*/
- ( void )scanForDevices:(NSError**)error
if (CBCentralManagerStatePoweredOn == self .centralManager.state)
//取回已连接的service设备
NSArray* retrievedPeripherals = [ self .centralManagerretrieveConnectedPeripheralsWithServices:@[ self .serviceUUID]];
for (CBPeripheral* peripheral in retrievedPeripherals)
//NSLog(@"retrieved peripheral:%@", peripheral);
[ self .delegateclient: self didDiscoverDevice:peripheral.identifier];
//启动扫描
if ( self .advertisementUUID)
[ self .centralManager scanForPeripheralsWithServices:@[ self .advertisementUUID ] options:@ CBCentralManagerScanOptionAllowDuplicatesKey:@YES ];
else
[ self .centralManager scanForPeripheralsWithServices: nil options:@ CBCentralManagerScanOptionAllowDuplicatesKey:@YES ];
// [self.centralManager scanForPeripheralsWithServices:nil options:nil];
else
if (error != NULL )
*error = [NSErrorerrorWithDomain:HCErrorDomaincode:(SRVClientErrorUnknown+ self .centralManager.state)userInfo: nil ];
NSLog(@"[NSError errorWithDomain:HCErrorDomain code:(SRVClientErrorUnknown + self.centralManager.state) userInfo:nil];");
4.3 发现外围设备
- ( void )centralManager:(CBCentralManager*)centraldidDiscoverPeripheral:(CBPeripheral*)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber*)RSSI
NSString*peripheralName = peripheral.name;
if (peripheralName == nil || peripheralName.length==0)
return ;
if ([peripheralNameisEqualToString:SRV_CLIENT_DEV_NAME] || [peripheralNameisEqualToString:SRV_CLIENT_DFU_NAME])
4.4 连接外围设备
//蓝牙连接成功回调
- ( void )centralManager:(CBCentralManager*)centraldidConnectPeripheral:(CBPeripheral*)peripheral
[ self .centralManager stopScan];
peripheral.delegate= self ;
self .commandNo=0;
NSLog(@"[D] CentralManager Discover services.");
NSLog(@"%@", self .peripheral);
self .peripheral.delegate= self ;
[ self .peripheral discoverServices:@[ self .serviceUUID]];
NSLog(@"%@", self .serviceUUID);
//定时获取RSSI
if ( self .needReadRSSI)
[ self readPeripheralRSSI];
if (! self .rssiTimer)
self .rssiTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
target: self
selector: @selector (readPeripheralRSSI)
userInfo: nil
repeats: YES ];
#pragma mark 连接外设——失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
NSLog(@"%@", error);
#pragma mark 取消与外设的连接回调
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
NSLog(@"%@", peripheral);
4.5 获得外围设备的服务
//发现服务的回调
- ( void )peripheral:(CBPeripheral*)peripheraldidDiscoverServices:(NSError*)error
NSLog(@"%@---didDiscoverServices",peripheral);
if (error)
NSLog(@"[E] peripheral didDiscoverServices error: %@", error.localizedDescription);
[ self cancelConnection];
return ;
for (CBService* service in peripheral.services)
NSLog(@"[D] Discover characteristics. For service = %@", service);
[peripheraldiscoverCharacteristics: nil forService:service];
//发现特征的回调
- ( void )peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
if (error)
NSLog(@"[E] peripheral didDiscoverCharacteristicsForService error: %@", error.localizedDescription);
[ self cancelConnection];
return ;
NSLog(@"[D] peripheral DiscoverCharacteristics = %@", service.characteristics);
//订阅特征
for (CBCharacteristic*characteristic in service.characteristics)
if (characteristic.properties & (CBCharacteristicPropertyNotify|CBCharacteristicPropertyIndicate))
if (!characteristic.isNotifying)
if ([ self .ignoreCharacteristicUUIDscontainsObject:characteristic.UUID])
continue ;
NSLog(@"[D] Enable notify value. For characteristic = %@", characteristic);
//d订阅特性当数据频繁改变时用 setNotifyValue 不频繁时用readValueForCharacteristic
[peripheralsetNotifyValue: YES forCharacteristic:characteristic];
// 订阅后的callback
- ( void )peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
if (error)
NSLog(@"[E] peripheral didUpdateNotificationStateForCharacteristic error: %@", error.localizedDescription);
[ self cancelConnection];
return ;
if ([ self isAllCharacteristicNotificationEnabled])
NSLog(@"订阅成功");
//authorizeRequest 授权认证
[ self .delegate clientDidPrepareForOperation: self ];
// [self.delegate clientDidPrepareForOperation:self];
4.6 从外围设备读取数据
// peripheral主动发数据,包括写命令后主动返回的状态 读数据的回调
- ( void )peripheral:(CBPeripheral*)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error
if (error)
NSLog(@"[E] peripheral didUpdateValueForCharacteristic error: %@ %@", error.localizedDescription,characteristic);
[ self cancelConnection];
[ self cleanupOperationUnexpectedly];
return ;
NSLog(@"%@",peripheral);
NSLog(@"%@",characteristic);
[ self .delegate client: self didUpdateValueForCharacteristic:characteristic.UUID value:characteristic.value];
if ([characteristic.UUIDisEqual: self .ctrlptUUID])
if (CTRLPTProgressWaitResp == self .ctrlptProgress)
4.7 给外围设备发送(写入)数据
- ( BOOL )performOperationSegment:(CBCharacteristic*)characteristic
BOOL isLastSegment;
uint8_tsegment[20];
uint16_tindex =0;
uint16_tsegLength;
NSIntegerforwardLength = self .forwardFlow.length;
if ((forwardLength - self .forwardOffset) > (20- index))
isLastSegment = NO ;
segLength = (20- index);
else
isLastSegment = YES ;
segLength = (forwardLength - self .forwardOffset);
memcpy(&segment[index], & self .forwardFlow.bytes[ self .forwardOffset], segLength);
self .forwardOffset+= segLength;
index += segLength;
NSData*writeData = [NSDatadataWithBytes:segmentlength:index];
NSLog(@"[D] Write value = %@. For characteristic = %@", writeData, characteristic);
[ self .peripheral writeValue:writeData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];//对于操控类蓝牙,数据写入要求非常快,其中writeWithSponce写入消耗的时间是writeWithoutSponce的2.3倍,因此尽量改写成writeWithoutSponce来提升写入速率
return isLastSegment;
//是否写入成功的回调
- ( void )peripheral:(CBPeripheral*)peripheraldidWriteValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error
if (error)
NSLog(@"[E] peripheral didWriteValueForCharacteristic error: %@", error);
[ self cancelConnection];
[ self cleanupOperationUnexpectedly];
return ;
NSLog(@"写入成功----%@",characteristic);
if ([characteristic.UUIDisEqual: self .ctrlptUUID])
if (CTRLPTProgressWritting == self .ctrlptProgress)
if ([ self performOperationSegment:characteristic])
self .ctrlptProgress = CTRLPTProgressWaitResp;
self .backwardFlow.length=0;
self .backwardOffset=0;
4.8 如何解析蓝牙数据
//判断是否第一个包,若是,取出包长度
if (0== self .backwardOffset&& length >=2)
uint16_tcommandLength;
[characteristicDatagetBytes:&commandLengthlength: sizeof (commandLength)];
offset += sizeof (commandLength);
self .backwardLength= commandLength;
[ self .backwardFlowappendData:[characteristicDatasubdataWithRange:NSMakeRange(offset, length - offset)]];
else
[ self .backwardFlowappendData:characteristicData];
iOS蓝牙编程指南 -- 核心蓝牙概述
小引
随着穿戴设备和智能家居的热情不断,app蓝牙的开发也很火热,基于iOS蓝牙的开发资料有不少,但是最最值得学习的必然是apple自家的文档啦,我之前的项目基于蓝牙4.0,开发过程中用到Core Bluetooth
框架,算是我学习的笔记吧!涉及到几个部分,我打算分开把他们整理出来,本篇文章通过对Core Bluetooth Programming Guide的翻译,为大家介绍iOS蓝牙4.0编程的一些术语和概念,后续文章将会简单介绍下代码的流程。本人实力有限,了解的深度不是很广,还请各位看官轻点拍砖!
话不多说说,让我们进入正题吧:
注:本文译自Core Bluetooth Programming Guide
核心蓝牙概述
Core Bluetooth
框架使你的 Mac/iOS app 能够与低功耗蓝牙设备进行通讯。例如,你的app能够搜寻,探索低功耗蓝牙设备,并与之互动,如心率监听器,数字恒温器,甚至能够与其它iOS设备进行交互。
该框架基于BLE4.0规范,直接适用于蓝牙低功率设备的使用。也就是说,该框架隐藏了很多开发规范的底层实现细节,使您更容易开发出与蓝牙低功耗设备进行交互的app。因为该说明中涉及到蓝牙框架的一些概念和术语在本说明中已经被广泛采用,本文将向你介绍这个 Core Bluetooth
框架中的一些关键术语和概念。
Central 和 Peripheral 在蓝牙交互中的角色
所有涉及蓝牙低功耗的交互中有两个主要的角色:中心Central
和外围设备Perpheral
。根据一些传统的客户端-服务端
结构,Peripheral
通常具有其他设备所需要的数据,而Central
通常通过使用Perpheral
的信息来实现一些特定的功能。如下图所示,例如,一个心率监听器可能含有一些有用的信息,你的 Mac/iOS app 可能需要以用户友好的方式显示用户的心率。
Central 发现并连接广播中的 Peripheral
Peripheral
向外广播一些广告包形式的数据,广告包是一个相对较小的束,可能包含Peripheral
提供的有用信息资料,如外设的名称和主要功能。例如,一个数字恒温器可以广告包含其中的一个房间的即时温度。在低功耗蓝牙中,广播是Peripheral
被获知的主要方式。
从另一方面说,Central
可以扫描和监听任何对广播内容感兴趣的Peripheral
。如下图,Central
可以请求连接任何已对外广播内容的Peripheral
。
数据在 Peripheral 中如何构成
连接到Peripheral
的目的是为了对它所提供的数据进行探索和交互。在此之前,理解数据在Peripheral
中是怎样构成的将会对我们有所帮助。
Peripheral
包含一个或者多个Service
以及有关其连接信号强度的有用信息。Service
是指实现一个函数或者功能的设备(或者设备的一部分)的数据采集和相关行为的集合。例如,一个心率监听器的Service
可能包含从监听心率传感器采集的心率数据。
而Service
本身由Characteristic
或者其他被包含的Service
所组成。Characteristic
提供了更多有关Peripheral
的Service
中的详细内容。例如,刚才描述的心率service
中可以包含一个用来描述该设备的心率传感器所记录身体位置的characteristic
或者包含发送测量心率数据的Characteristic
。如下图,表示了一个心率监听器可能包含的Service
和Characteristic
。
Central 在 Peripheral 上的数据探索及交互
在Central
成功与Peripheral
建立连接后,就能发现到Peripheral
提供的所有的Service
和Characteristic
。(广播数据可能只包含一部分可见的Service
)
Central
可以通过读取或者写入Service
中Characteristic
的value
与Peripheral
进行交互。例如,你的 app 可能从数字恒温器上请求当前的室内温度,或者为恒温器提供一个数值以设置室内温度。
Central,Peripherals 以及 Peripheral数据如何表示
有关低功耗蓝牙交互中的主要角色和数据在Core Bluetooth
中以简单明了的方式表示。
Central 端的对象
当你使用本地Central
和远程Peripheral
进行交互,您将在低功耗蓝牙Central
侧执行操作。除非你是建立一个本地Peripheral
设备,并使它由一个Central
端请求响应,大多数的蓝牙交互由Central
端完成。
本地 Central 和远程 Peripheral
在Central
端,本地Central
设备表示为CBCentralManager。这些对象用来管理发现或连接远程Peripheral
设备(表示为CBPeripheral),包括扫描,发现和连接广播中的Peripheral
。如下图所示:
远程 Peripheral 数据表示为 CBService 和CBCharacteristic
当你与远程Peripheral
(表示为CBPeripheral
)进行数据交互时,你将处理它的Service
和Characteristic
。在Core Bluetooth
框架中,远程Peripheral
的Service
表示为CBService
。相类似的,远程Peripheral
中Service
的Characteritic
表示为CBCharacteristic
。如下图所示:
Peripheral 端的对象
OS X v10.9和iOS6以上的Mac/iOS设备能够可以设置成低功耗蓝牙的Peripheral
,为其他Mac/iPhone/iPad 传输数据。当你设置好你的设备使其能够实现Peripheral
的角色,你就可以完成低功耗蓝牙交互的Peripheral
端功能。
本地 Peripheral 和远程 Central
在Peripheral
端,一个Peripheral
设备表示为CBPeripheralManager
。该对象用于管理那些包含本地Peripheral
设备的Service
和Characteristic
数据的Service
,通过广播这些服务的方式发布到远程Central
设备(表示为CBCentral
)。Peripheral manager
对象同样可以响应远程Central
的读取和写入请求。如下图所示:
本地 Peripheral 数据表示为 CBMutableService 和 CBMutableCharacteristic
当你设置好和本地Peripheral
(表示为CBPeripheralManager
)数据交互,就可以处理Service
和Characteristic
的可变版本。在Core Bluetooth
框架中,本地Peripheral
的Service
表示为CBMutableService
。同样地,本地Peripheral
中Service
的Characteristic
表示为CBMutableCharacteristic
。如下图所示:
以上是关于iOS 蓝牙的主要内容,如果未能解决你的问题,请参考以下文章