蓝牙概念
蓝牙2.0为传统蓝牙,传统蓝牙也称为经典蓝牙.
蓝牙4.0因为低耗电,所以也叫做低功耗蓝(BLE).它将三种规格集一体,包括传统蓝牙技术、高速技术和低耗能技术.
苹果在iOS 6系统之后开始支持BLE 4.0,iPhone4s,iPod 5,iPad 3等之后的机型开始内嵌BLE4.0硬件,因此在开发前请先确认你的开发环境符合上述要求,并且苹果在BLE4.0之后,对外部的连接设备已经不再需要MFI认证了,当然你的外设肯定得要有蓝牙4.0模块。
BLE支持两种部署方式
双模式
低功耗蓝牙功能集成在现有的经典蓝牙控制器中,或在现有经典蓝牙技术芯片上增加低功耗堆栈,整体架构基本不变,因此成本增加有限.单模式
面向高度集成、紧凑的设备,使用一个轻量级连接层(Link Layer)提供超低功耗的待机模式操作、简单设备恢复和可靠的点对多点数据传输,还能让联网传感器在蓝牙传输中安排好低功耗蓝牙流量的次序,同时还有高级节能和安全加密连接.
蓝牙各版本使用选择
蓝牙2.0,不上架
使用私有API,手机需要越狱.蓝牙2.0,要上架
进行MFI认证,使用ExternalAccessory框架.手机不需要越狱.- 蓝牙4.0,要上架
使用CoreBluetooth框架,手机不需要越狱.(CoreBluetooth是基于BLE来开发的) - 说明:对于小的硬件厂商来说,MFI认证通过几率不大,不仅耗钱还耗时,所以,还是推荐使用蓝牙4.0.
(MFI:Make for ipad ,iphone, itouch 专们为苹果设备制作的设备)
蓝牙4.0使用解析
基本知识
central:中心,连接硬件的设备.
peripheral:外设,被连接的硬件.
说明:外设在一直广播,当你创建的中心对象在扫描外设时,就能够发现外设.
如图所示:
service:服务.
characteristic:特征.
说明:一个外设包含多个服务,而每一个服务中又包含多个特征,特征包括特征的值和特征的描述.每个服务包含多个字段,字段的权限有read(读)、write(写)、notify(通知).
蓝牙4.0分为两种模式
中心模式流程
- 建立中心角色 [[CBCentralManager alloc] initWithDelegate:self queue:nil]
- 扫描外设
scanForPeripherals
- 发现外设
didDiscoverPeripheral
- 连接外设
connectPeripheral
- 连接失败
didFailToConnectPeripheral
- 连接断开
didDisconnectPeripheral
- 连接成功
didConnectPeripheral
- 连接失败
- 扫描外设中的服务
discoverServices
- 发现并获取外设中的服务
didDiscoverServices
- 扫描外设对应服务的特征
discoverCharacteristics
- 发现并获取外设对应服务的特征
didDiscoverCharacteristicsForService
- 给对应特征写数据
writeValue:forCharacteristic:type:
- 订阅特征的通知
setNotifyValue:forCharacteristic:
- 根据特征读取数据
didUpdateValueForCharacteristic
- 扫描外设
外设模式流程
- 建立外设角色
- 设置本地外设的服务和特征
- 发布外设和特征
- 广播服务
- 响应中心的读写请求
- 发送更新的特征值,订阅中心
BabyBluetooth介绍
BabyBluetooth是一个最简单易用的蓝牙库,基于CoreBluetooth的封装,并兼容ios和mac osx。
BabyBluetooth的优点:
基于原生CoreBluetooth框架封装的轻量级的开源库,可以帮你更简单地使用CoreBluetooth API。
CoreBluetooth所有方法都是通过委托完成,代码冗余且顺序凌乱。BabyBluetooth使用block方法,可以重新按照功能和顺序组织代码,并提供许多方法减少蓝牙开发过程中的代码量。
链式方法体,代码更简洁、优雅。
通过channel切换区分委托调用,并方便切换
便利的工具方法
完善的文档,且项目处于活跃状态,不断的更新中
github上star最多的纯Bluetooch类库(非PhoneGap和SensorTag项目)
BabyBluetooth使用
- 初始化
//初始化BabyBluetooth 蓝牙库
self.baby = [BabyBluetooth shareBabyBluetooth];
//设置蓝牙委托
[self babyDelegate];
//设置委托后直接可以使用,无需等待CBCentralManagerStatePoweredOn状态
self.baby.scanForPeripherals().begin();
//蓝牙网关初始化和委托方法设置
-(void)babyDelegate{
__weakCycle;
/**
设备状态改变的block | when CentralManager state changed
*/
[self.baby setBlockOnCentralManagerDidUpdateState:^(CBCentralManager *central) {
if (central.state != CBCentralManagerStatePoweredOn) {
NSLog(@"蓝牙未开启");
} else {
NSLog(@"开启了蓝牙");
}
}];
/**
找到Peripherals的block | when find peripheral
*/
[self.baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
NSLog(@"搜索到了设备:%@",peripheral.name);
if ([peripheral.name isEqualToString:@"iLock"]) {
[weakSelf.baby cancelScan];
[weakSelf.baby AutoReconnect:peripheral];
weakSelf.baby.having(peripheral).enjoy();
}
}];
/**
连接Peripherals成功的block
| when connected peripheral
*/
[self.baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
NSLog(@"设备:%@--连接成功",peripheral.name);
}];
/**
连接Peripherals失败的block
| when fail to connect peripheral
*/
[self.baby setBlockOnFailToConnect:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
NSLog(@"设备:%@--连接失败",peripheral.name);
}];
//设置发现设备的Services的委托
[self.baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) {
for (CBService *service in peripheral.services) {
NSLog(@"搜索到服务:%@",service.UUID.UUIDString);
}
}];
//设置发现设service的Characteristics的委托
[self.baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
NSLog(@"===service name:%@",service.UUID);
for (CBCharacteristic *c in service.characteristics) {
NSLog(@"charateristic name is :%@",c.UUID);
}
}];
//设置读取characteristics的委托
[self.baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
}];
//设置发现characteristics的descriptors的委托
[self.baby setBlockOnDiscoverDescriptorsForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
NSLog(@"===characteristic name:%@",characteristic.service.UUID);
for (CBDescriptor *d in characteristic.descriptors) {
NSLog(@"CBDescriptor name is :%@",d.UUID);
}
}];
//设置读取Descriptor的委托
[self.baby setBlockOnReadValueForDescriptors:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
NSLog(@"Descriptor name:%@ value is:%@",descriptor.characteristic.UUID, descriptor.value);
}];
//过滤器
//设置连接的设备的过滤器
__block BOOL isFirst = YES;
[self.baby setFilterOnConnectToPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
//这里的规则是:连接第一个AAA打头的设备
if(isFirst && [peripheralName hasPrefix:@"i"]){
isFirst = NO;
return YES;
}
return NO;
}];
}