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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。