一、前言
BLE,全称蓝牙低能耗(Bluetooth Low Energy)技术是低成本、短距离、可互操作的鲁棒性无线技术,工作在免许可的2.4GHz ISM射频频段,隶属于蓝牙4.0规范。它从一开始就设计为超低功耗(ULP)无线技术。它利用许多智能手段最大限度地降低功耗。蓝牙低能耗技术采用可变连接时间间隔,这个间隔根据具体应用可以设置为几毫秒到几秒不等。另外,因为BLE技术采用非常快速的连接方式,因此平时可以处于“非连接”状态(节省能源),此时链路两端相互间只是知晓对方,只有在必要时才开启链路,然后在尽可能短的时间内关闭链路
iOS开发中常用的蓝牙框架也就下面这几个。GameKit.framework,一般用于游戏开发中iOS设备之间的连接;MultipeerConnectivity.framework,iOS7后推出,个人理解可以实现airdrop类似的功能;ExternalAccessory.framework,可用于基于MFI认证的设备连接;CoreBluetooth.framework,低功耗蓝牙,基于蓝牙4.0,开放度高。大部分场景下采用的都是CoreBluetooth.framework,比如现在常见的物联网设备
CoreBluetooth.framework框架结构如下图所示,基于CoreBluetooth.framework做蓝牙开发,我们首先需要了解几个概念
中心设备(central)、外设(peripheral):这两个概念放在一起说明比较容易理解。比如当你用摩拜App去解锁自行车的时候,你的手机就是中心设备,摩拜车就是外设。如果是从mac利用airdrop传文件到手机,那么电脑就是中心设备,你的手机则又变成了外设。对应结构图中就有中心模式(CBCentralManager)和外设模式(CBPeripheralManager)两种
服务(service):每个外设一般都会设计若干个服务,每个服务对应一个事件。比如摩拜车,就可能会有一个解锁的服务。每个服务都会有一个唯一的标识(UUID)用于区分。这个标识一般为16bit、32bit或者128bit
特征(characteristic):每个服务下面可以有若干个特征,设备之间的通讯就是通过这些特征值来实现的。比如在解锁摩拜车的时候,可能会有一个车锁状态的特征,解锁或者锁车之后回去修改这个特征值。同样每个特征也会有一个唯一的标识(UUID)用于区分
特征的属性:对应特征的作用域,某些特征是只读、某些是可读可写、某些是广播等等
基于上面几个概念和结构图,在说明一下使用的流程
1、中心模式:创建对象->搜索外设->连接外设->扫描服务->获取特征->基于特征做数据交互->完成后断开连接
2、外设模式:创建对象->设置服务、特征、属性->发布广播->设置读写等委托方法
下面详细介绍这两种模式的使用方法。其中外设模式在iOS开发中一般使用频率不高,主要为中心模式
二、外设模式
1、引入框架、定义标识
#import <CoreBluetooth/CoreBluetooth.h>
#define notiyCharacteristicUUID @"FFF1"
#define readwriteCharacteristicUUID @"FFF2"
#define readCharacteristicUUID @"FFE1"
#define ServiceUUID1 @"FFF0"
#define ServiceUUID2 @"FFE0"
#define LocalNameKey @"MyBlueDevice"
2、创建外设模式管理,初始化并设置CBPeripheralManagerDelegate代理
@property (nonatomic,strong) CBPeripheralManager *peripheralManager;
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
/*
蓝牙设备打开需要一定时间,打开成功后会进入委托方法
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral;
模拟器永远也不会得CBPeripheralManagerStatePoweredOn状态,所以做测试的时候请使用真机
*/
3、在回调中初始化服务、特征等
#pragma mark CBPeripheralManagerDelegate
-(void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
switch (peripheral.state) {
case CBManagerStatePoweredOn:
{
NSLog(@"设备已打开....");
[self setupBlueInfo];
break;
}
default:
NSLog(@"异常状态:%ld",(long)peripheral.state);
break;
}
}
-(void)setupBlueInfo
{
CBUUID *CBUUIDCharacteristicUserDescriptionStringUUID = [CBUUID UUIDWithString:CBUUIDCharacteristicUserDescriptionString];
//可以通知的Characteristic
CBMutableCharacteristic *notiyCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:notiyCharacteristicUUID] properties:CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable];
//可读写的characteristics
self.readwriteCharacteristic = [[CBMutableCharacteristic alloc]initWithType:[CBUUID UUIDWithString:readwriteCharacteristicUUID] properties:CBCharacteristicPropertyWrite | CBCharacteristicPropertyRead value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
//设置descript