IOS 上蓝牙协议只支持4.0以上
如果需要调用蓝牙协议需要添加<CoreBluetooth/CoreBluetooth.h>框架
1.中心管理者
IOS中的蓝牙分为: 中心管理设计模式和外设管理设计模式
/**
* 中心管理者
*/
@property(nonatomic,strong) CBCentralManager * BleCenter ;
把中心管理者设置成属性后,写一个中心管理者的懒加载
-(CBCentralManager *)BleCenter
{
if (!_BleCenter) {
_BleCenter= [[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
}
return _BleCenter;
}
这里注意在初始化重新管理者的时候必须遵守协议CBCentralManagerDelegate,并且需要在主线程中实现。
2.扫描外设
- 扫描的方法防治cMgr成功打开的代理方法中
- 只有设备成功打开,才能开始扫描,否则会报错
初始化中心管理者完成后会触发一个方法是必须实现的
-(void)centralManagerDidUpdateState:(CBCentralManager *)central
CBCentralManagerStateUnknown:
(@"未知情况")
CBCentralManagerStateResetting:
(@"重置")
CBCentralManagerStateUnsupported:
(@"无支持")
CBCentralManagerStatePoweredOff:
(@"关闭")
CBCentralManagerStateUnauthorized:
(@"未经授权")
CBCentralManagerStatePoweredOn:
//扫描周边设备搜索成功后会调用找到外设的代理方法
[self.BleCenter scanForPeripheralsWithServices:nil options:nil];
(@"开启")
3.接下来可以连接设备
如果你没有设备,可以下载一个app叫lightbule的app去模拟一个设备
判断设备号是否扫描到
@param central 中心管理者
@param peripheral 外设
@param advertisementData 外设携带的数据
@param RSSI 外设发出的信号强度
//找到外设代理方法
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral
*)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
在这个方法中我们需要对连接到的外设进行筛选,根据以下两点来筛选。
/*
peripheral = <CBPeripheral: 0x166668f0 identifier =
C69010E7-EB75-E078-FFB4-421B4B951341, Name = "OBand-75", state =
disconnected>, advertisementData = {
kCBAdvDataChannel = 38;
kCBAdvDataIsConnectable = 1;
kCBAdvDataLocalName = OBand;
kCBAdvDataManufacturerData = <4c69616e 0e060678 a5043853 75>;
kCBAdvDataServiceUUIDs = (
FEE7
);
kCBAdvDataTxPowerLevel = 0;
}, RSSI = -55
根据打印结果,我们可以得到运动手环它的名字叫 OBand-75
*/
//需要对连接到的外设进行筛选,1.根据信号强度 2.通过设备名(设备字符串的前缀)
if ([peripheral.name hasPrefix:@"截取设备字符串的前缀"] && (RSSI.integerValue
>40)) {
//标记外设,让他的生命周期
= vc
self.peripheral =
peripheral;
//设备连接
[self.BleCenter connectPeripheral:self.peripheral options:nil];
}
4.1 获取外设的services
- 首先设置外设的代理,并搜寻services
- 然后在代理方法peripheral:didDiscoverServices:中遍历services
//中心管理者连接外设成功
-(void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral
*)peripheral
{
NSLog(@"%s, line = %d,%@连接成功",__FUNCTION__,__LINE__,peripheral.name);
//设置代理
self.peripheral.delegate = self;
//发现服务,传nil代表不过滤
//这里会触发 发现外设的服务器后调用的方法
[self.peripheral discoverServices:nil];
}
//丢失连接
-(void)centralManager:(CBCentralManager *)central
didDisconnectPeripheral:(CBPeripheral *)peripheral
error:(NSError *)error
{
NSLog(@"%s, line = %d,%@丢失连接",__FUNCTION__,__LINE__,peripheral.name);
}
//外设连接失败
-(void)centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral
*)peripheral
error:(NSError *)error
{
NSLog(@"%s, line = %d,%@外设连接失败",__FUNCTION__,__LINE__,peripheral.name);
}
//发现外设的服务后调用
-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@"%s, line = %d, erro = %@", __FUNCTION__,__LINE__,error.localizedDescription);
}
for (CBService *service in peripheral.services) {
//发现服务后,让设备在发现服务内部的特征们
[peripheral discoverIncludedServices:nil forService:service];
}
}
4.2 获取外设的characteris,获取Characteristics的值,获取Characteristics的Descriptor以及Descriptor的值
//发现外设服务里的特征的时候调用的代理方法
-(void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error
{
NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
for (CBCharacteristic *cha in service.characteristics) {
NSLog(@"%s, line = %d,char = %@",__FUNCTION__,__LINE__,cha);
//获取特征对应的描述
[peripheral discoverDescriptorsForCharacteristic:cha];
//获取特征的值
[peripheral readValueForCharacteristic:cha];
}
}
//更新特征对应的值,时候调用
-(void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)
characteristic error:(NSError *)error
{
NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
for (CBDescriptor *descriptor in characteristic.descriptors) {
//它会触发 发现外设的特征描述数组
[peripheral readValueForDescriptor:descriptor];
}
}
//更新特征和对应的描述,时候调用
-(void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForDescriptor:(CBDescriptor
*)descriptor
error:(NSError *)error
{
//当描述的值更新的时候,直接调用此方法
[peripheral readValueForDescriptor:descriptor];
NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
}
// 发现外设的特征的描述数组
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverDescriptorsForCharacteristic:(nonnull CBCharacteristic
*)characteristic
error:(nullable NSError *)error
{
NSLog(@"%s, line =
%d",__FUNCTION__,__LINE__);
//
在此处读取描述即可
for (CBDescriptor *descriptor in characteristic.descriptors) {
[peripheral readValueForDescriptor:descriptor];
}
}
5.写数据到特征中
/**
* 写入数据
*/
// 需要注意的是特征的属性是否支持写数据
-(void)LXC_peripheral:(CBPeripheral *)peripheral
didWriteData:(NSData *)data
forCharacteristic:(nonnull CBCharacteristic
*)characteristic
{
NSLog(@"%s, line = %d
,characteristic.properties = %lu",__FUNCTION__,__LINE__,(unsigned long)characteristic.properties);
//此时由于枚举属性是NS_OPTIONS,所以一个枚举可能对应多个类型,所以判断不能用 = ,应该用 &
if (characteristic.properties &CBCharacteristicPropertyWriteWithoutResponse) {
//写入值
[peripheral writeValue:data //写入数据
forCharacteristic:characteristic //写给哪个
type:CBCharacteristicWriteWithResponse]; //通过此响应记录是否成功写入
}
}
6.订阅特征的通知
/**
* 外设特征订阅通知
*/
-(void)LXC_peripheral:(CBPeripheral *)peripheral
regNotifyWithCharacteristic:(nonnull CBCharacteristic
*)characteristic
{
// 设置通知, 数据会进入
peripheral:didUpdateValueForCharacteristic:error:方法
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
-(void)LXC_peripheral:(CBPeripheral *)peripheral
CancleRegNotifyWithCharacteristic:(nonnull CBCharacteristic
*)characteristic
{ //外设为特征取消通知
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
}
7.断开连接
/**
* 断开连接
*/
-(void)LXC_dismissConentedWithperipheral:(CBPeripheral
*)peripheral
{
//停止扫描
[self.BleCenter stopScan];
//断开连接
[self.BleCenter cancelPeripheralConnection:peripheral];
}