IOS Ble蓝牙开发实现方法
本篇博文阐述如何开发Ble蓝牙。在蓝牙中的一些常见服务,扫描,以及链接;
- 主蓝牙类文件.h
- 主蓝牙类文件.m
- UUID文件
- 蓝牙列表展示的文件
一:引入Ble蓝牙的框架
BuleHelp.h
#import//导入蓝牙框架 #import #import"DeviceModel.h" #import"Constants.h" #import"CommonUserDefaults.h" #import"CommonUtil.h" #import"TempDB.h" #defineCOMMAND_PACKET_MIN_SIZE7 @interfaceBlueHelp:NSObject //蓝牙的设备搜索显示在列表中 @property(nonatomic,strong)NSMutableArray *periperals; //连接peripheral @property(nonatomic,strong)CBPeripheral*peripheral; //连接peripheral @property(nonatomic,strong)CBPeripheral*selectperipheral; //中心管理者 @property(nonatomic,strong)CBCentralManager*centerManager; @property(nonatomic,strong)DeviceModel*deviceModel; //设备列表 @property(nonatomic,strong)NSMutableArray*deviceList; @property(nonatomic,strong)NSMutableArray*commandArray; //是否进行ota升级 @property(nonatomic)BOOLisOta; @property(nonatomic)BOOLisWritePacketDataSuccess; @property(strong,nonatomic)NSString*checkSumType; /*! *@propertyisApplicationValid * *@discussionflagusedtocheckwhethertheapplicationwritingissuccess * */ @property(nonatomic)BOOLisApplicationValid; /*! *@propertycheckSum * *@discussioncheckSumreceivedfromthedeviceforwritingasinglerow * */ @property(assign)uint8_tcheckSum; /*! *@propertystartRowNumber * *@discussionDeviceflashstartrownumber * */ @property(nonatomic)intstartRowNumber; /*! *@propertyendRowNumber * *@discussionDeviceflashendrownumber * */ @property(nonatomic)intendRowNumber; /*! *@propertysiliconIDString * *@discussionsiliconIDfromthedeviceresponse * */ @property(strong,nonatomic)NSString*siliconIDString; /*! *@propertysiliconRevString * *@discussionsiliconrevfromthedeviceresponse * */ @property(strong,nonatomic)NSString*siliconRevString; //是否发送数据 @property(nonatomic)BOOLisSendData; @property(strong,nonatomic)CommonUtil*commonUtil; @property(strong,nonatomic)TempDB*tempDB; @property(strong,nonatomic)NSDate*currentDate; //时间格式化 @property(strong,nonatomic)NSDateFormatter*dateformatter; @property(strong,nonatomic)NSString*deviceName; //@property(nonatomic,strong)NSUserDefaults*userDefaults; @property(nonatomic,strong)CommonUserDefaults*userDefaults; //发送温度数据 @property(nonatomic,strong)CBCharacteristic*sendtempcharateristic; //发送OTA数据 @property(nonatomic,strong)CBCharacteristic*sendotacharateristic; //高/低温度数据 //@property(nonatomic,strong)CBCharacteristic*sendhighalarmcharateristic; // //@property(nonatomic,strong)CBCharacteristic*sendlowalarmcharateristic; //ota @property(nonatomic,strong)CBCharacteristic*senddfucharateristic; //发送字符串'CR'清除机子上的最大值(3个字节) @property(nonatomic,strong)CBCharacteristic*senddcrstrateristic; //发送字符串'PD'机子关机(3个字节) @property(nonatomic,strong)CBCharacteristic*senddoutstrateristic; //静音 @property(strong,nonatomic)CBCharacteristic*sendmutealarmcharateristic; //calset @property(strong,nonatomic)CBCharacteristic*sendcalsetcharateristic; //intervaltime @property(strong,nonatomic)CBCharacteristic*sendintervaltimecharateristic; //alarmswitch @property(strong,nonatomic)CBCharacteristic*sendalarmswitchcharateristic; //tempunit @property(strong,nonatomic)CBCharacteristic*sendtempunitcharateristic; @property(strong,nonatomic)CBCharacteristic*sendlowalarmswitchcharateristic; ///<===============方法区块=======================> +(id)sharedManager; -(NSMutableArray*)getDeviceList; -(NSMutableArray*)getPeriperalList; -(void)startScan; //连接蓝牙 -(void)contentBlue:(int)row; //断开蓝牙 -(void)disContentBle; //断开ota的蓝牙连接 -(void)disContentOtaBle; //温度符号 -(void)writeTempUnit:(NSString*)value; //写入报警开关 -(void)writeAlarmSwitch:(NSString*)value; //写入mutealarm -(void)writeMuteAlarm:(NSString*)value; //写入CRCLERVULE -(void)writeClearCR:(NSString*)value; //写入intervaltime -(void)writeIntervalTime:(NSString*)value; //写入calset -(void)writeCalSet:(NSString*)value; //写入设备的开关按钮 -(void)writeBluePD:(NSString*)value; //写入低温报警 //-(void)writeLowAlarm:(NSString*)value; // ////写入高温报警 //-(void)writeHighAlarm:(NSString*)value; //OTA固件升级又称为DFU -(void)writeUpdateOTA:(NSString*)value; -(void)writeBlueOTA:(NSString*)value; -(void)wirteBlueOTAData:(NSData*)value; -(void)writeLowAlarmSwitch:(NSString*)value; -(void)discoverCharacteristicsWithCompletionHandler:(void(^)(BOOLsuccess,NSError*error))handler; -(void)updateValueForCharacteristicWithCompletionHandler:(void(^)(BOOLsuccess,idcommand,NSError*error))handler; -(void)stopUpdate; -(void)setCheckSumType:(NSString*)type; -(NSData*)createCommandPacketWithCommand:(uint8_t)commandCodedataLength:(unsignedshort)dataLengthdata:(NSDictionary*)packetDataDictionary; -(void)writeValueToCharacteristicWithData:(NSData*)databootLoaderCommandCode:(unsignedshort)commandCode; /* *停止扫描 */ -(void)stopScan; //是否是第一次连接设备 @property(assign,nonatomic)BOOLisconnected; //当前的时间 @property(nonatomic,assign)longcurrentTime; @property(nonatomic,strong)NSString*macAddre; @property(nonatomic,strong)NSString*macName; -(void)disMainOtaBle; @end
BuleHelp.m
//程序运行后,会自动调用的检查蓝牙的方法并扫描蓝牙的方法
-(void)centralManagerDidUpdateState:(CBCentralManager*)central{
if([centralstate]==CBCentralManagerStatePoweredOff){
NSLog(@"CoreBluetoothBLEhardwareispoweredoff");
}
elseif([centralstate]==CBCentralManagerStatePoweredOn){
NSLog(@"CoreBluetoothBLEhardwareispoweredonandready");
[selfstartScan];
}
elseif([centralstate]==CBCentralManagerStateUnauthorized){
NSLog(@"CoreBluetoothBLEstateisunauthorized");
}
elseif([centralstate]==CBCentralManagerStateUnknown){
NSLog(@"CoreBluetoothBLEstateisunknown");
}
elseif([centralstate]==CBCentralManagerStateUnsupported){
NSLog(@"CoreBluetoothBLEhardwareisunsupportedonthisplatform");
}
}
/*
*程序运行的时候开始扫描
*/
-(void)startScan{
_periperals=[[NSMutableArrayalloc]init];
_deviceList=[[NSMutableArrayalloc]init];
//2.利用中心设备扫描外部设备
[_centerManagerscanForPeripheralsWithServices:niloptions:nil];
}
/*
*停止扫描
*/
-(void)stopScan{
[_centerManagerstopScan];
}
/* *设备中可以包含Deviceaddre地址放在key:kCBAdvDataManufacturerData中既可以得到 *1.硬件开发工程师把地址写入到设备的厂家信息中。 */ -(void)centralManager:(CBCentralManager*)centraldidDiscoverPeripheral:(CBPeripheral*)peripheraladvertisementData:(NSDictionary*)advertisementDataRSSI:(NSNumber*)RSS{ //判断如果数组中不包含当前扫描到的外部设备才保存 if(![_periperalscontainsObject:peripheral]){ //包扣3种设备都需要去搜索 if([peripheral.namecontainsString:@"TMW012BT"]||[peripheral.namecontainsString:@"OTA"]){ NSLog(@"DATA:%@",advertisementData); NSArray*keys=[advertisementDataallKeys]; for(inti=0;i<[keyscount];++i){ idkey=[keysobjectAtIndex:i]; NSString*keyName=(NSString*)key; NSData*value=[advertisementDataobjectForKey:key]; if([keyNameisEqualToString:@"kCBAdvDataManufacturerData"]){ NSLog(@"valueis%@",value); NSString*result=[selfconvertDataToHexStr:value]; NSLog(@"reslutis%@",result); if(result!=nil&&result.length>4){ NSString*d=[resultsubstringFromIndex:4]; NSLog(@"DIS%@",d); //小写 //NSString*lower=[testlowercaseString]; //大写 NSString*upper=[duppercaseString]; _macAddre=[NSStringstringWithFormat:@"S/N:%@",upper]; } } if([keyNameisEqualToString:@"kCBAdvDataLocalName"]){ NSString*aStr=(NSString*)value; NSLog(@"astris%@",aStr); _macName=aStr; } } _deviceModel=[DeviceModelnew]; _deviceModel.deviceName=_macName; //蓝牙地址 _deviceModel.deviceAddre=_macAddre; intrssi=[RSSintValue]; NSString*range=[NSStringstringWithFormat:@"%d",rssi]; NSString*rs=[NSStringstringWithFormat:@"RSSI%@dBm",range]; //添加到里面 [self.periperalsaddObject:peripheral]; _deviceModel.deviceRssi=rs; [_deviceListaddObject:_deviceModel]; } } }
//解析广播里面的数据 -(void)getAdvertisementData:(NSDictionary*)advertisementData{ NSArray*keys=[advertisementDataallKeys]; for(inti=0;i<[keyscount];++i){ idkey=[keysobjectAtIndex:i]; NSString*keyName=(NSString*)key; NSObject*value=[advertisementDataobjectForKey:key]; if([keyNameisEqualToString:@"kCBAdvDataManufacturerData"]){ printf("key:%s\n",[keyNamecStringUsingEncoding:NSUTF8StringEncoding]); NSString*values=(NSString*)value; NSLog(@"valuesis%@",values); } } }
/*
*连接蓝牙设备给外部调用的方法
*传入的是相对应的行数
*/
-(void)contentBlue:(int)row{
[_centerManagerconnectPeripheral:_periperals[row]options:nil];
}
-(void)disContentBle{
//关键的断开蓝牙通知也要停止掉
if((_peripheral!=nil&&_sendtempcharateristic!=nil)){
[_peripheralsetNotifyValue:NOforCharacteristic:_sendtempcharateristic];
[selfdisconnectPeripheral:_peripheral];
}
}
/*
*断开ota的连接
*/
-(void)disContentOtaBle{
if(_peripheral!=nil&&_sendotacharateristic!=nil){
[_peripheralsetNotifyValue:NOforCharacteristic:_sendotacharateristic];
[selfdisconnectPeripheral:_peripheral];
}
}
-(void)disMainOtaBle{
if(_peripheral!=nil){
[selfdisconnectPeripheral:_peripheral];
}
}
-(void)disconnectPeripheral:(CBPeripheral*)peripheral
{
[_centerManagercancelPeripheralConnection:peripheral];
}
//连接成功
-(void)centralManager:(CBCentralManager*)centraldidConnectPeripheral:(CBPeripheral*)peripheral{
NSLog(@"连接成功");
if(peripheral!=nil){
//停止扫描这个用于自动连接的时候
[_centerManagerstopScan];
//设备名称
_deviceName=peripheral.name;
_selectperipheral=peripheral;
peripheral.delegate=self;
//再去扫描服务
[peripheraldiscoverServices:nil];
}
}
//连接失败
-(void)centralManager:(CBCentralManager*)centraldidFailToConnectPeripheral:(CBPeripheral*)peripheralerror:(nullableNSError*)error{
NSLog(@"连接失败,失败原因:%@",error);
NSString*disContentBlue=@"discontentblue";
NSDictionary*blueDiscontent=[NSDictionarydictionaryWithObject:disContentBlueforKey:@"disconnect"];
//发送广播连接失败
[[NSNotificationCenterdefaultCenter]postNotificationName:@"disNofiction"object:niluserInfo:blueDiscontent];
}
//断开连接
-(void)centralManager:(CBCentralManager*)centraldidDisconnectPeripheral:(CBPeripheral*)peripheralerror:(NSError*)error{
NSLog(@"断开连接");
NSString*disContentBlue=@"discontentblue";
//_blueiscon=@"Disconnect";
NSDictionary*blueDiscontent=[NSDictionarydictionaryWithObject:disContentBlueforKey:@"disconnect"];
//发送广播连接失败
[[NSNotificationCenterdefaultCenter]postNotificationName:@"disNofiction"object:niluserInfo:blueDiscontent];
}
//只要扫描到服务就会调用,其中的外设就是服务所在的外设
-(void)peripheral:(CBPeripheral*)peripheraldidDiscoverServices:(NSError*)error{
if(error){
NSLog(@"扫描服务出现错误,错误原因:%@",error);
}else{
//获取外设中所扫描到的服务
for(CBService*serviceinperipheral.services){
//拿到需要扫描的服务,例如FFF0比如打印温度数据
//把所有的service打印出来
//从需要的服务中查找需要的特征
//从peripheral的services中扫描特征
[peripheraldiscoverCharacteristics:nilforService:service];
}
}
}
//只要扫描到特征就会调用,其中的外设和服务就是特征所在的外设和服务
-(void)peripheral:(CBPeripheral*)peripheraldidDiscoverCharacteristicsForService:(nonnullCBService*)serviceerror:(nullableNSError*)error{
if(error){
NSLog(@"扫描特征出现错误,错误原因:%@",error);
}else{
//遍历特征,拿到需要的特征进行处理
for(CBCharacteristic*characteristicinservice.characteristics){
NSLog(@"characteristicis%@",characteristic.UUID);
//如果是温度数据处理
if([characteristic.UUIDisEqual:BOOT_TEMPVALUE_UUID]){
//将全部的特征信息打印出来
_isconnected=true;
_peripheral=peripheral;
_sendtempcharateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//如果是ota进行ota升级
elseif([characteristic.UUIDisEqual:BOOT_OTA_WIRTE_UUID]){
_peripheral=peripheral;
_sendotacharateristic=characteristic;
//设置通知
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
_isOta=TRUE;
[_userDefaultssaveOta:_isOta];
//[_setBool:_isOtaforKey:@"isOTA"];
NSString*s=@"OTA";
NSDictionary*tempOta=[NSDictionarydictionaryWithObject:sforKey:@"ota"];
[[NSNotificationCenterdefaultCenter]postNotificationName:@"tempOTA"object:niluserInfo:tempOta];
}
//CAL
elseif([characteristic.UUIDisEqual:BOOT_CAL_UUID]){
_sendcalsetcharateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//intervaltime
elseif([characteristic.UUIDisEqual:BOOT_INTERVALTIME_UUID]){
_sendintervaltimecharateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//Tempunit
elseif([characteristic.UUIDisEqual:BOOT_TEMPUNIT_UUID]){
_sendtempunitcharateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//DFU
elseif([characteristic.UUIDisEqual:BOOT_DFU_UUID]){
_senddfucharateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//发送字符串'CR'清除机子上的最大值(3个字节)
elseif([characteristic.UUIDisEqual:BOOT_CRSTRING_UUID]){
_senddcrstrateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
//发送字符串'PD'机子关机(3个字节)
elseif([characteristic.UUIDisEqual:BOOT_OUTSTRING_UUID]){
_senddoutstrateristic=characteristic;
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
else{
}
}
}
}
/*
设置通知
*/
-(void)notifyCharacteristic:(CBPeripheral*)peripheral
characteristic:(CBCharacteristic*)characteristic{
[peripheralsetNotifyValue:YESforCharacteristic:characteristic];
[_centerManagerstopScan];
}
/*
取消通知
*/
-(void)cancelNotifyCharacteristic:(CBPeripheral*)peripheral
characteristic:(CBCharacteristic*)characteristic{
[peripheralsetNotifyValue:NOforCharacteristic:characteristic];
}
/*
接收数据解析
*/
-(void)peripheral:(CBPeripheral*)peripheraldidUpdateValueForCharacteristic:(CBCharacteristic*)characteristicerror:(NSError*)error{
//是否为Ota
if(!self.isSendOta){
if(self.readtempcharater==characteristic){
NSString*tmpData=[self.cmUtilgetTempTMWData:characteristic];
if(tmpData!=nil){
//开始处理数据
NSArray*data=[tmpDatacomponentsSeparatedByString:@","];
TmpModel*tp=[[TmpModelalloc]init];
tp.tmp=data[0];
tp.max=data[1];
tp.unit=data[2];
//电量
tp.bat=data[3];
NSDictionary*tempDict=[NSDictionarydictionaryWithObject:tpforKey:@"tempData"];
[[NSNotificationCenterdefaultCenter]postNotificationName:@"tempNofiction"object:niluserInfo:tempDict];
if([tp.batisEqual:@"1"]){
//低电量广播
NSDictionary*LowDict=[NSDictionarydictionaryWithObject:tpforKey:@"lowData"];
[[NSNotificationCenterdefaultCenter]postNotificationName:@"lowNofiction"object:niluserInfo:LowDict];
}
}
}
}
//======================写入数据区块========================//
/*
写入发送时间
*/
-(void)writeIntervalTime:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendtimecharater!=nil){
[selfwriteData:valueforCharacteristic:self.sendtimecharaterperiperalData:periperal];
}
}
/*
写入温度单位
*/
-(void)writeTmpUnit:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendunitcharater!=nil){
[selfwriteData:valueforCharacteristic:self.sendunitcharaterperiperalData:periperal];
}
}
/*
写入Cal值
*/
-(void)writeCalValue:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendcalcharater!=nil){
[selfwriteData:valueforCharacteristic:self.sendcalcharaterperiperalData:periperal];
}
}
/*
发送Ota使得设备进入Ota
*/
-(void)writeDfuValue:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.senddfucharater!=nil){
[selfwriteData:valueforCharacteristic:self.senddfucharaterperiperalData:periperal];
}
}
/*
发送MaxTemp实现清零选项
*/
-(void)writeClearValue:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendclearcharater!=nil){
[selfwriteData:valueforCharacteristic:self.sendclearcharaterperiperalData:periperal];
}
}
/*
发送关机选项实现远程开关机
*/
-(void)writeCloseValue:(NSString*)valueperiperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendclosecharater!=nil){
[selfwriteData:valueforCharacteristic:self.sendclosecharaterperiperalData:periperal];
}
}
/*
所有写入的数据处理
*/
-(void)writeData:(NSString*)valueforCharacteristic:(CBCharacteristic*)characteristicperiperalData:(CBPeripheral*)periperal{
NSData*data=[valuedataUsingEncoding:NSUTF8StringEncoding];
if(characteristic.properties&CBCharacteristicPropertyWriteWithoutResponse)
{
[periperalwriteValue:dataforCharacteristic:characteristictype:CBCharacteristicWriteWithoutResponse];
}else
{
[periperalwriteValue:dataforCharacteristic:characteristictype:CBCharacteristicWriteWithResponse];
}
}
此篇文章阐述到这,基本BLE蓝牙开发实现都详细的描述了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。