iOS蓝牙开发 蓝牙连接和数据读写
在做蓝牙开发之前,最好先了解一些概念:
服务(services):蓝牙外设对外广播的必定会有一个服务,可能也有多个,服务下面包含着一些特征,服务可以理解成一个模块的窗口;
特征(characteristic):存在于服务下面的,一个服务下面也可以存在多个特征,特征可以理解成具体实现功能的窗口,一般特征都会有value,也就是特征值,特征是与外界交互的最小单位;
UUID:可以理解成蓝牙上的唯一标识符(硬件上肯定不是这个意思,但是这样理解便于我们开发),为了区分不同的服务和特征,或者给服务和特征取名字,我们就用UUID来代表服务和特征。
蓝牙连接可以大致分为以下几个步骤
1.建立一个CentralManager实例进行蓝牙管理
2.搜索外围设备
3.连接外围设备
4.获得外围设备的服务
5.获得服务的特征
6.从外围设备读数据
7.给外围设备发送数据
其他:提醒
首先我们先导入系统的BLE的框架
#import
必须遵守2个协议
/**中心管理者*/
@property(nonatomic,strong)CBCentralManager*cMgr;
/**连接到的外设*/
@property(nonatomic,strong)CBPeripheral*peripheral;
1.建立一个CentralManager实例进行蓝牙管理
-(CBCentralManager*)cmgr
{
if(!_cmgr){
_cMgr=[[CBCentralManageralloc]initWithDelegate:selfqueue:nil];
}
return_cMgr;
}
//只要中心管理者初始化就会触发此代理方法判断手机蓝牙状态
-(void)centralManagerDidUpdateState:(CBCentralManager*)central
{
switch(central.state){
case0:
NSLog(@"CBCentralManagerStateUnknown");
break;
case1:
NSLog(@"CBCentralManagerStateResetting");
break;
case2:
NSLog(@"CBCentralManagerStateUnsupported");//不支持蓝牙
break;
case3:
NSLog(@"CBCentralManagerStateUnauthorized");
break;
case4:
{
NSLog(@"CBCentralManagerStatePoweredOff");//蓝牙未开启
}
break;
case5:
{
NSLog(@"CBCentralManagerStatePoweredOn");//蓝牙已开启
//在中心管理者成功开启后再进行一些操作
//搜索外设
[self.cMgrscanForPeripheralsWithServices:nil//通过某些服务筛选外设
options:nil];//dict,条件
//搜索成功之后,会调用我们找到外设的代理方法
//-(void)centralManager:(CBCentralManager*)centraldidDiscoverPeripheral:(CBPeripheral*)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber*)RSSI;//找到外设
}
break;
default:
break;
}
}
2.搜索外围设备(我这里为了举例,采用了自己身边的一个手环)
//发现外设后调用的方法
-(void)centralManager:(CBCentralManager*)central//中心管理者
didDiscoverPeripheral:(CBPeripheral*)peripheral//外设
advertisementData:(NSDictionary*)advertisementData//外设携带的数据
RSSI:(NSNumber*)RSSI//外设发出的蓝牙信号强度
{
//NSLog(@"%s,line=%d,cetral=%@,peripheral=%@,advertisementData=%@,RSSI=%@",__FUNCTION__,__LINE__,central,peripheral,advertisementData,RSSI);
/*
peripheral=,advertisementData={
kCBAdvDataChannel=38;
kCBAdvDataIsConnectable=1;
kCBAdvDataLocalName=OBand;
kCBAdvDataManufacturerData=<4c69616e0e060678a504385375>;
kCBAdvDataServiceUUIDs=(
FEE7
);
kCBAdvDataTxPowerLevel=0;
},RSSI=-55
根据打印结果,我们可以得到运动手环它的名字叫OBand-75
*/
//需要对连接到的外设进行过滤
//1.信号强度(40以上才连接,80以上连接)
//2.通过设备名(设备字符串前缀是OBand)
//在此时我们的过滤规则是:有OBand前缀并且信号强度大于35
//通过打印,我们知道RSSI一般是带-的
if([peripheral.namehasPrefix:@"OBand"]){
//在此处对我们的advertisementData(外设携带的广播数据)进行一些处理
//通常通过过滤,我们会得到一些外设,然后将外设储存到我们的可变数组中,
//这里由于附近只有1个运动手环,所以我们先按1个外设进行处理
//标记我们的外设,让他的生命周期=vc
self.peripheral=peripheral;
//发现完之后就是进行连接
[self.cMgrconnectPeripheral:self.peripheraloptions:nil];
NSLog(@"%s,line=%d",__FUNCTION__,__LINE__);
}
}
3.连接外围设备
//中心管理者连接外设成功
-(void)centralManager:(CBCentralManager*)central//中心管理者
didConnectPeripheral:(CBPeripheral*)peripheral//外设
{
NSLog(@"%s,line=%d,%@=连接成功",__FUNCTION__,__LINE__,peripheral.name);
//连接成功之后,可以进行服务和特征的发现
//设置外设的代理
self.peripheral.delegate=self;
//外设发现服务,传nil代表不过滤
//这里会触发外设的代理方法-(void)peripheral:(CBPeripheral*)peripheraldidDiscoverServices:(NSError*)error
[self.peripheraldiscoverServices:nil];
}
//外设连接失败
-(void)centralManager:(CBCentralManager*)centraldidFailToConnectPeripheral:(CBPeripheral*)peripheralerror:(NSError*)error
{
NSLog(@"%s,line=%d,%@=连接失败",__FUNCTION__,__LINE__,peripheral.name);
}
//丢失连接
-(void)centralManager:(CBCentralManager*)centraldidDisconnectPeripheral:(CBPeripheral*)peripheralerror:(NSError*)error
{
NSLog(@"%s,line=%d,%@=断开连接",__FUNCTION__,__LINE__,peripheral.name);
}
4.获得外围设备的服务&5.获得服务的特征
//发现外设服务里的特征的时候调用的代理方法(这个是比较重要的方法,你在这里可以通过事先知道UUID找到你需要的特征,订阅特征,或者这里写入数据给特征也可以)
-(void)peripheral:(CBPeripheral*)peripheraldidDiscoverCharacteristicsForService:(CBService*)serviceerror:(NSError*)error
{
NSLog(@"%s,line=%d",__FUNCTION__,__LINE__);
for(CBCharacteristic*chainservice.characteristics){
//NSLog(@"%s,line=%d,char=%@",__FUNCTION__,__LINE__,cha);
}
}
5.从外围设备读数据
//更新特征的value的时候会调用(凡是从蓝牙传过来的数据都要经过这个回调,简单的说这个方法就是你拿数据的唯一方法)你可以判断是否
-(void)peripheral:(CBPeripheral*)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error
{
NSLog(@"%s,line=%d",__FUNCTION__,__LINE__);
if(characteristic==@"你要的特征的UUID或者是你已经找到的特征"){
//characteristic.value就是你要的数据
}
}
6.给外围设备发送数据(也就是写入数据到蓝牙)
这个方法你可以放在button的响应里面,也可以在找到特征的时候就写入,具体看你业务需求怎么用啦
[self.peripheralewriteValue:_batteryDataforCharacteristic:self.characteristictype:CBCharacteristicWriteWithResponse]; //第一个参数是已连接的蓝牙设备;第二个参数是要写入到哪个特征;第三个参数是通过此响应记录是否成功写入
//需要注意的是特征的属性是否支持写数据
-(void)yf_peripheral:(CBPeripheral*)peripheraldidWriteData:(NSData*)dataforCharacteristic:(nonnullCBCharacteristic*)characteristic
{
/*
typedefNS_OPTIONS(NSUInteger,CBCharacteristicProperties){
CBCharacteristicPropertyBroadcast=0x01,
CBCharacteristicPropertyRead=0x02,
CBCharacteristicPropertyWriteWithoutResponse=0x04,
CBCharacteristicPropertyWrite=0x08,
CBCharacteristicPropertyNotify=0x10,
CBCharacteristicPropertyIndicate=0x20,
CBCharacteristicPropertyAuthenticatedSignedWrites=0x40,
CBCharacteristicPropertyExtendedProperties=0x80,
CBCharacteristicPropertyNotifyEncryptionRequiredNS_ENUM_AVAILABLE(NA,6_0)=0x100,
CBCharacteristicPropertyIndicateEncryptionRequiredNS_ENUM_AVAILABLE(NA,6_0)=0x200
};
打印出特征的权限(characteristic.properties),可以看到有很多种,这是一个NS_OPTIONS的枚举,可以是多个值
常见的又read,write,noitfy,indicate.知道这几个基本够用了,前俩是读写权限,后俩都是通知,俩不同的通知方式
*/
//NSLog(@"%s,line=%d,char.pro=%d",__FUNCTION__,__LINE__,characteristic.properties);
//此时由于枚举属性是NS_OPTIONS,所以一个枚举可能对应多个类型,所以判断不能用=,而应该用包含&
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。