iOS 蓝牙4.0与智能硬件之间的交互
本文档主要讲述iOS苹果手机通过蓝牙4.0与智能硬件之间的交互。也就是苹果设备对智能硬件进行扫描、连接、发命令、以及接收反馈等操作:
- coreBluetooth框架
- 具体使用方法
CoreBluetooth.framework
CoreBluetooth.framework 是苹果给开发者提供的蓝牙4.0开发框架。其中包含了玉智能硬件交互的相关API。其中主要包含:
- CBCentralManager (中心设备) 也就是iPhone、iPad等设备。
-
CBPeripheral (外围设备) 智能硬件设备,如:智能手环、智能电子秤、智能体温计等等市场上的智能硬件。
利用以上的两个类来完成iOS设备与智能硬件之间的操作。
初始化CBCentral
不管是什么框架初始化是最基本的,初始化如下:
#import<CoreBluetooth/CoreBluetooth.h>
@implementation BluetoothManager
-(id)init
{
self = [super init];
if(self != null)
{
self.centralManager = [[CBCentralManager alloc] initWithDelegate:nil queue:nil];
self.centralManager.delegate = self;
//扫描到的设备集合
self.foundPeripheralsArray = [NSMutableArray array];
//连接到的设备集合
self.connectPeripheralsArray = [NSMutableArray array];
...
}
return self;
}
@end
使用方法
1、检查设备是否已开启蓝牙
首先,要想与设备连接,第一件事情就是要先判断目前蓝牙开关是否开启。当然如果是关着的,并且程序内已有蓝牙权限的情况下系统也会提醒的。
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case CBCentralManagerStatePoweredOn:
//蓝牙设备已开启
break;
case CBManagerStatePoweredOff:
//蓝牙设备已关闭
break;
case CBManagerStateUnsupported:
//设备不支持的状态
break;
case CBManagerStateResetting:
//设备正在重置
break;
default:
break;
}
}
2、扫描与停止扫描(CBPeripheral)
确认好蓝牙设备已经开启,下面进行扫描周围的蓝牙设备。
注:开启扫描之前清空掉之前扫描过的设备数组
- (void)ScanDevice
{
if(self.foundPeripheralsArray.length > ){
[self.foundPeripheralsArray removeAllObjects];
}
//扫描外围设备
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
有开启扫描,自然也有停止扫描
-(void)StopScanDevice
{
//停止扫描
[self.centralManager stopScan];
}
扫描回调的delegate函数
如centralManager的delegate已开启。扫描到的设备都会进入下面的函数
/**
* 发现了设备。
*
* @param central 中央设备
* @param peripheral 外围设备
* @param advertisementData 广播数据
* @param RSSI 信号强度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
//一般进行过滤掉无关设备的操作
//过滤完无关的设备之后,过滤掉重复的设备并加入到数组里
//如果只连接特定的设备,找到之后直接连接
[self ConnectPeripheral:peripheral];
}
3、连接与断开
找到了要连接的设备之后
- (void)ConnectPeripheral:(CBPeripheral *)peripheral
{
for(int i = ; i < ; i++)
{
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
注:为什么要发5次之多,这是为了能更加稳定的与设备进行连接。因为发一次的话,有些时候是收不到的。体会会很差。所以这里面要尝试发很多条保证让设备收到这个命令。
连接设备的delegate函数
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
//设备已经连接成功了,不需要再连接其他设备就停止扫描
[self StopScanDevice];
peripheral.delegate = self;
//扫描设备的服务
[peripheral discoverServices:nil];
}
与连接设备相反也有失去连接的时候也有对应的函数
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
//失去了与外围设备的的连接,所以在这里要重新开启扫描来找连接过的设备
[self ScanDevice];
/*
能进入此函数说明有两种情况
1.是因为信号不好与设备断开了连接
2.用户主动去断开连接
*/
}
4、扫描服务
扫描设备的服务delegate函数
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
BOOL found = NO;
for (CBService *s in peripheral.services)
{
if ([s.UUID isEqual:[CBUUID UUIDWithString:@"XXXX"]])
{
found = YES;
break;
}
}
//如果找到了服务,继续扫描服务下的特征值,没有找到就断开与设备的连接
if(found)
{
for (CBService *s in peripheral.services)
{
[peripheral discoverCharacteristics:nil forService:s];
}
}
else
{
[self.centralManager cancelPeripheralConnection:peripheral];
}
}
5、扫描特征
扫描特征的delegate函数
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if([service.UUID isEqual:[CBUUID UUIDWithString:@"XXXX"]])
{
//发送命令
}
else if([service.UUID isEqual:[CBUUID UUIDWithString:@"180A"]])
{
//iOS可以通过这个特征值来获取设备的MAC地址
for(CBCharacteristic * characteristic in service.characteristics)
{
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A23"]])
{
[peripheral readValueForCharacteristic:characteristic];
}
}
}
}
注:与Android不一样iOS是无法从广播上直接获取设备的MAC地址所以通过设备的某个特殊服务下面的特征值来获取MAC地址。
6、数据交互
特征值发生变化时的delegate
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
//接收到的特征值
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"XXXX"]])
{
//通过UUID来区分它的具体功能。
}
else if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A23"]])
{
//在这里获取到了设备的MAC地址,不过并不是按照顺序来的。所以要再对数据进行处理
NSString *value = [NSString stringWithFormat:@"%@",characteristic.value];
NSMutableString *macString = [[NSMutableString alloc] init];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
[macString appendString:@":"];
[macString appendString:[[value substringWithRange:NSMakeRange(, )] uppercaseString]];
}
}
常用的命令格式
- Write(写入)
- Read(读取)
- Notification(通知)
Write(写入)
Read(读取)
Notification(通知)