今天项目中的蓝牙功能已经开发完毕,总结一下。
CoreBluetooth.framework:功能强大的蓝牙框架,只要该设备支持蓝牙4.0,就可以进行蓝牙传输,只要该设备支持蓝牙4.0。
CoreBluetooth中分为两大设备:中央设备和外围设备。
1.如果一个设备设置为外围设备,那他负责发布并广播服务,通知周围的中央设备它的可用服务和特征,相当于通信中的服务端
2.如果设备设置为中央设备,那他负责和外围设备建立连接,连接成功可以使用外围设备的服务和特征,相当于通信中的客户端。
即:
外围设备 —–类似于——-》服务器端
中央设备 —–类似于——-》客户端
这两大设备进行交互靠的是服务和特征。服务和特征都有唯一标识CBUUID来确定。
1.服务CBService:
中央设备只有通过服务才能与外围设备进行数据传输,类似于客户端通过网址URL才能与服务器连接一样
2.特征CBCharacteristic:
每个服务可以有多个特征,中央设备必须订阅外围设备服务的特征值,才能获取外围设备的数据,类似于GET请求可以请求获取服务器数据,POST请求可以向服务器传输数据一样。
一般我们需要的是中央设备,外围设备可以是手环,耳机……
设备作为中央设备 实现过程如下:
1.创建中央设备管理器对象,遵循代理CBCentralManagerDelegate
self.manager = [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue()];
self.BleViewPerArr = [[NSMutableArray alloc]initWithCapacity:1];
2.代理方法 判断设备的蓝牙是否开启
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
switch (central.state) {
case CBCentralManagerStatePoweredOff:
NSLog(@"您的手机蓝牙未开启");
break;
case CBCentralManagerStateResetting:
NSLog(@"检测到您的手机蓝牙重置");
break;
case CBCentralManagerStateUnsupported:
NSLog(@"检测到您的手机不支持蓝牙4.0");
break;
case CBCentralManagerStateUnauthorized:
NSLog(@"检测到您的手机蓝牙没有授权");
break;
case CBCentralManagerStateUnknown:
NSLog(@"未知状态");
break;
case CBCentralManagerStatePoweredOn:
NSLog(@"检测到您的手机蓝牙正常开启,可以扫描外围设备");
break;
default:
break;
}
}
只有在蓝牙正常开启状态下才可以进行扫描
3.开始扫描外围设备
/*
判断状态开始扫瞄周围设备 第一个参数为空则会扫瞄所有的可连接设备 你可以
指定一个CBUUID对象 从而只扫瞄注册用指定服务的设备
*/
[self.manager scanForPeripheralsWithServices:nil options:nil];
//清空所有外设数组 没扫描一次最好清空数据源 以备战展示用
[self.BleViewPerArr removeAllObjects];
4.扫描完成会调用CBCentralManagerDelegate代理方法
/*
发现外围设备调用
central 中央设备管理器
peripheral 外围设备
advertisementData 设备信息
RSSI 信号质量(信号强度)可以用判断周边设备离中央设备的远近
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI方法{
if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/)
{
return;
}
//存放在数据源中
NSString *pername=[NSString stringWithFormat:@"%@",peripheral.name];
//判断是否存在@"你的设备名"
NSRange range=[pername rangeOfString:@"你的设备名"];
//如果从搜索到的设备中找到指定设备名,和BleViewPerArr数组没有它的地址
//加入BleViewPerArr数组
if(range.location!=NSNotFound&&[_BleViewPerArr containsObject:peripheral]==NO){
[_BleViewPerArr addObject:peripheral];
}
//刷新自己的列表
[_tableView reloadData];
}
以上就扫描到了外围设备,当然还需要将外围设备,展示在列表上
/*蓝牙对象在下面环节会查找出来,被放进BleViewPerArr数组里面,是CBPeripheral对象,取出name
*/
CBPeripheral *per=(CBPeripheral *)_BleViewPerArr[indexPath.row];
cell.textLabel.text =per.name;
5.接下来就是连接设备了,遵循外围设备对象代理CBPeripheralDelegate 我是在tableView的didSelect方法里连接的,如果确定只有一个设备,可以下载上面的方法里 直接连接
CBPeripheral *peripheral=(CBPeripheral *)_BleViewPerArr[indexPath.row];
//设定周边设备,指定代理者
peripheral.delegate = self;
//连接设备
[_manager connectPeripheral:peripheral
options:nil];
6.中央设备管理器成功连接到外围设备后调用
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
//设置设备代理
[peripheral setDelegate:self];
//大概获取服务和特征,或许只获取你的设备蓝牙服务的uuid数组,一个或者多个;
//用 UUIDWithString 添加数组
[peripheral discoverServices:nil];
//停止扫描
[_manager stopScan];
}
<font color=#0099ff size=2>
7.连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"error ==%@",error);
}
8.外围设备寻找到服务后调用CBPeripheralDelegate代理方法
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}
//已发现可用服务
//遍历查找到的服务
CBUUID *serviceUUID = [CBUUID UUIDWithString:@"你的设备服务的uuid"];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID];
for (CBService *service in peripheral.services) {
if([service.UUID isEqual:@"你的设备服务的uuid"]){
//外围设备查找指定服务中的特征,characteristics为nil,表示寻找所有特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
9.围设备寻找到特征后调用CBPeripheralDelegate代理方法
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
if (error)
{
NSLog(@"Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
return;
}
NSLog(@"服务:%@",service.UUID);
// 特征
for (CBCharacteristic *characteristic in service.characteristics)
{
NSLog(@"%@",characteristic.UUID);
//发现特征
//注意:uuid 分为可读,可写,要区别对待!!!
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
{
NSLog(@"监听:%@",characteristic);//监听特征
//保存characteristic特征值对象
//以后发信息也是用这个uuid
_characteristic1 = characteristic;
[_discoveredPeripheral setNotifyValue:YES forCharacteristic:characteristic];
}
/*当然,你也可以监听多个characteristic特征值对象
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"你的特征uuid"]])
{
//同样用一个变量保存,demo里面没有声明变量,要去声明
_characteristic2 = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:_characteristic2];
NSLog(@"监听:%@",characteristic);//监听特征
}
*/
}
}
10.外围设备读取到特征值后调用
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error)
{
NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
return;
}
//收到的数据
if (characteristic.value) {
NSString *value = [[NSString alloc] initWithData:characteristic.value
encoding:NSUTF8StringEncoding];
NSLog(@"读取到特征值:%@",value);
}else{
NSLog(@"未发现特征值.");
}
}
至此 整个中央设备连接外围设备连接成功完成!
总结:
蓝牙连接可以大致分为以下几个步骤
1.建立一个Central Manager蓝牙管理对象
2.搜索外围设备
3.连接外围设备
4.获得外围设备的服务
5.获得服务的特征