iOS 蓝牙开发(一)
前期回顾
iOS 蓝牙开发(二)
iOS 蓝牙开发(三)
iOS 蓝牙开发(四)
一、基本概念
- 1.1,中心设备(central):是发起连接的主设备,如:App。
- 1.2,外设(peripheral):被连接的设备称为外部设备,即外设, 如:体脂称,健康手环等;
- 1.3,服务(CBService): 外设可以包含一个或多个服务,它是用于实现装置的功能或特征数据相关联的行为集合。
- 1.4,特征(CBCharacteristic):每个服务可以对应多个特征,它是提供外设服务进一步的细节。
开始前先记录运行后的扫描结果
扫描结果和lightBule的对比二,蓝牙相关实现
在iOS中蓝牙相关实现都是在CoreBluetooth这个framework中的,所以我们创建一个单例类中需要先导入#import <CoreBluetooth/CoreBluetooth.h>
,再后即可使用这个单例类进行管理我们蓝牙的扫描、连接、状态等实现。
- 2.1, 初始化蓝牙
CBCentralManager
dispatch_queue_t centralQueue = dispatch_queue_create("com.acadsoc.wgazjbuletoothsdk",DISPATCH_QUEUE_SERIAL);
NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey : [NSNumber numberWithBool:YES], CBCentralManagerOptionRestoreIdentifierKey : @"com.hykj.wgazjbuletoothsdk"};
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:options];
// self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
self.resultStr = @"";
self.services = [[NSMutableArray alloc]init];
- 2.2,扫描周边可连接蓝牙设备
当我们在扫描周边外设之前需要判断蓝牙是否可用,在- (void)centralManagerDidUpdateState:(CBCentralManager *)central
函数中进行获取设备蓝牙的更新。
判断手机蓝牙状态
CBManagerStateUnknown = 0, 未知
CBManagerStateResetting, 重置中
CBManagerStateUnsupported, 不支持
CBManagerStateUnauthorized, 未验证
CBManagerStatePoweredOff, 未启动
CBManagerStatePoweredOn, 可用
当central.state
为CBManagerStatePoweredOn即可开始扫描, 具体方法[self.centralManager scanForPeripheralsWithServices:nil options:nil]
当调用scanForPeripheralsWithServices:options:
函数时就会实时调用其代理方法- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (self.stateUpdateBlock) {
self.stateUpdateBlock(central.state);
}
switch (central.state)
{
case CBManagerStatePoweredOn:
NSLog(@"蓝牙已开启");
// 根据SERVICE_UUID来扫描外设,如果不设置SERVICE_UUID,则扫描所有蓝牙设备
// 第一个参数为CBUUID的数组,需要搜索特点服务的蓝牙设备,只要每搜索到一个符合条件的蓝牙设备都会调用didDiscoverPeripheral代理方法
[self startScan];
break;
case CBManagerStatePoweredOff:
NSLog(@"蓝牙已关闭, 请打开蓝牙");
break;
case CBManagerStateUnsupported:
NSLog(@"设备不支持蓝牙");
break;
case CBManagerStateUnauthorized:
NSLog(@"应用尚未被授权使用蓝牙");
break;
case CBManagerStateUnknown:
NSLog(@"未知错误,请重新开启蓝牙");
break;
case CBManagerStateResetting:
NSLog(@"蓝牙重置中");
[self stopScan];
break;
default:
NSLog(@"Central Manager did change state");
break;
}
}
// 开始扫描周围可用蓝牙
- (void)startScan {
//不重复扫描已发现设备
//CBCentralManagerScanOptionAllowDuplicatesKey设置为NO表示不重复扫瞄已发现设备,为YES就是允许。
//CBCentralManagerOptionShowPowerAlertKey设置为YES就是在蓝牙未打开的时候显示弹框
NSDictionary *option = @{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO],CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]};
// 第一个参数填nil代表扫描所有蓝牙设备,第二个参数options也可以写nil
[self.centralManager scanForPeripheralsWithServices:nil options:option];
}
// 扫描外设的代理方法,在该函数中揭开筛选出周边的蓝牙外设
// 在蓝牙于后台被杀掉时,重连之后会首先调用此方法,可以获取蓝牙恢复时的各种状态
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
NSString *perName = [[NSUserDefaults standardUserDefaults] objectForKey:@"conPeripheral"];
NSString *setOrDelNum = [[NSUserDefaults standardUserDefaults] objectForKey:@"setOrDel"];
// 检索到设备
if (self.discoverPeripheralBlcok) {
if (self.prefixString.length > 0) {
if ([peripheral.name hasPrefix:self.prefixString]) {
self.discoverPeripheralBlcok(central,peripheral,advertisementData,RSSI);
}
} else {
self.discoverPeripheralBlcok(central,peripheral,advertisementData,RSSI);
}
[self startScan];
}
if ([setOrDelNum isEqualToString:@"0"]) {
//有自动重连的设备
[[NSNotificationCenter defaultCenter]postNotificationName:PostAutoConnectionNotificaiton object:nil];
if ([peripheral.name isEqualToString:perName]) {
self.peripheral = peripheral;
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
}
peripheral
是外设类advertisementData
是广播的值,一般携带设备名,serviceUUID
等信息。RSSI
绝对值越大,表示信号越差,设备离的越远。如果想装换成百分比强度,(RSSI+100)/1001
(这是一个约数,蓝牙信号值并不一定是-100 - 0的值)
3,连接
蓝牙的连接是当中心设备扫描到可用外设后, 利用函数[self.centralManager connectPeripheral:peripheral options:nil];
进行链接, 当函数被调用后, 就会回调其对应的代理函数。
- 3.1,链接成功后的回调
// 蓝牙设备连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
[self.centralManager stopScan];
[self.peripheral setDelegate:self];
[self.peripheral discoverServices:nil];
//延时操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.connectSuccessBlock) {
self.connectSuccessBlock(peripheral,nil,self.writeCharacteristic);
} else {
//返回连接成功
if ([self.delegate respondsToSelector:@selector(automaticConnectionWithPerpheral:)]) {
[self.delegate automaticConnectionWithPerpheral:peripheral];
}
}
});
}
- 3.2, 链接失败后的回调
// 连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
if (self.connectFailureBlock) {
self.connectFailureBlock(peripheral,error);
}
}
4, 其他函数和代理方法
- 4.1,断开链接
// 断开蓝牙连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
[self disconectPeripheral];
if (error)
{
NSLog(@">>> didDisconnectPeripheral for %@ with error: %@", peripheral.name, [error localizedDescription]);
}
}
// 断开链接
- (void)disconectPeripheral {
if (self.peripheral) {
[self.centralManager cancelPeripheralConnection:self.peripheral];
}
}
- 4.2,停止扫描
// 停止扫描
- (void)stopScan
{
[self.centralManager stopScan];
}
5,中心管理供给外界使用方法
// 单例
+ (ZJAWGBluetoothManager *)defaultManager;
/**
当前蓝牙的状态
@param state 状态
*/
- (void)returnBluetoothStateWithBlock:(BTStateUpdateBlock)state;
/**
搜索蓝牙外设, 每次回调表示返回一个蓝牙外设信息
@param name 模糊搜索设备名称, 即目标设备名称包含的字段
@param discoverBlock 搜索到蓝牙外设后的回调
*/
- (void)scanPeripheralsWithName:(NSString *)name
discoverPeripheral:(BTDiscoverPeripheralBlock)discoverBlock;
/**
搜索蓝牙外设
@param discoverBlock 搜索蓝牙外设
*/
- (void)scanPeripheralsWithDiscoverPeripheral:(BTDiscoverPeripheralBlock)discoverBlock;
/**
连接某个蓝牙外设,并查询服务,特性,服务等描述
@param peripheral 要连接的蓝牙外设
@param complete 连接成功后的回调
@param failure 连接失败后的回调
*/
- (void)connectPeripheral:(CBPeripheral *)peripheral
complete:(BTConnectSuccessBlock)complete
failure:(BTConnectFailureBlock)failure;
总结
本篇笔记主要是记录如何初始化蓝牙的CBCentralManager
的中心管理类,并记录如何实现扫描周边外设、如何链接、获取蓝牙当前状态。