IOS Ble藍牙開發(fā)實現(xiàn)方法
更新時間:2019年12月25日 15:05:04 作者:Aftery的博客
這篇文章主要為大家詳細介紹了IOS Ble藍牙開發(fā)的實現(xiàn)方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本篇博文闡述如何開發(fā)Ble藍牙。在藍牙中的一些常見服務,掃描,以及鏈接;
- 主藍牙類文件.h
- 主藍牙類文件.m
- UUID文件
- 藍牙列表展示的文件
一:引入Ble藍牙的框架<CoreBluetooth/CoreBluetooth.h>
BuleHelp.h
#import <Foundation/Foundation.h> //導入藍牙框架 #import <CoreBluetooth/CoreBluetooth.h> #import "DeviceModel.h" #import "Constants.h" #import "CommonUserDefaults.h" #import "CommonUtil.h" #import "TempDB.h" #define COMMAND_PACKET_MIN_SIZE 7 @interface BlueHelp : NSObject //藍牙的設(shè)備搜索顯示在列表中 @property (nonatomic, strong) NSMutableArray <CBPeripheral*>*periperals; //連接peripheral @property(nonatomic,strong) CBPeripheral *peripheral; //連接peripheral @property(nonatomic,strong) CBPeripheral *selectperipheral; //中心管理者 @property (nonatomic, strong) CBCentralManager *centerManager; @property (nonatomic,strong) DeviceModel *deviceModel; //設(shè)備列表 @property (nonatomic,strong) NSMutableArray *deviceList; @property (nonatomic,strong) NSMutableArray *commandArray; //是否進行ota升級 @property (nonatomic) BOOL isOta; @property (nonatomic) BOOL isWritePacketDataSuccess; @property (strong,nonatomic) NSString * checkSumType; /*! * @property isApplicationValid * * @discussion flag used to check whether the application writing is success * */ @property (nonatomic) BOOL isApplicationValid; /*! * @property checkSum * * @discussion checkSum received from the device for writing a single row * */ @property (assign) uint8_t checkSum; /*! * @property startRowNumber * * @discussion Device flash start row number * */ @property (nonatomic) int startRowNumber; /*! * @property endRowNumber * * @discussion Device flash end row number * */ @property (nonatomic) int endRowNumber; /*! * @property siliconIDString * * @discussion siliconID from the device response * */ @property (strong,nonatomic) NSString *siliconIDString; /*! * @property siliconRevString * * @discussion silicon rev from the device response * */ @property (strong,nonatomic) NSString *siliconRevString; //是否發(fā)送數(shù)據(jù) @property (nonatomic) BOOL isSendData; @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; //發(fā)送溫度數(shù)據(jù) @property (nonatomic,strong) CBCharacteristic *sendtempcharateristic; //發(fā)送OTA數(shù)據(jù) @property (nonatomic,strong) CBCharacteristic *sendotacharateristic; //高/低溫度數(shù)據(jù) //@property (nonatomic,strong) CBCharacteristic *sendhighalarmcharateristic; // //@property (nonatomic,strong) CBCharacteristic *sendlowalarmcharateristic; //ota @property (nonatomic,strong) CBCharacteristic *senddfucharateristic; //發(fā)送字符串'CR'清除機子上的最大值(3個字節(jié)) @property (nonatomic,strong) CBCharacteristic *senddcrstrateristic; //發(fā)送字符串'PD'機子關(guān)機(3個字節(jié)) @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; ///<===============方法區(qū)塊=======================> + (id)sharedManager; -(NSMutableArray *)getDeviceList; -(NSMutableArray *)getPeriperalList; -(void)startScan; //連接藍牙 -(void)contentBlue:(int) row; //斷開藍牙 -(void)disContentBle; //斷開ota的藍牙連接 -(void)disContentOtaBle; //溫度符號 -(void)writeTempUnit:(NSString *)value; //寫入報警開關(guān) -(void)writeAlarmSwitch:(NSString *)value; //寫入mute alarm -(void)writeMuteAlarm:(NSString *)value; //寫入CR CLERVULE -(void)writeClearCR:(NSString *)value; //寫入interval time -(void)writeIntervalTime:(NSString *)value; //寫入cal set -(void)writeCalSet:(NSString *)value; //寫入設(shè)備的開關(guān)按鈕 -(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 (^) (BOOL success, NSError *error)) handler; -(void)updateValueForCharacteristicWithCompletionHandler:(void (^) (BOOL success,id command,NSError *error)) handler; -(void) stopUpdate; -(void) setCheckSumType:(NSString *) type; -(NSData *) createCommandPacketWithCommand:(uint8_t)commandCode dataLength:(unsigned short)dataLength data:(NSDictionary *)packetDataDictionary; -(void) writeValueToCharacteristicWithData:(NSData *)data bootLoaderCommandCode:(unsigned short)commandCode; /* * 停止掃描 */ -(void)stopScan; //是否是第一次連接設(shè)備 @property(assign,nonatomic) BOOL isconnected; //當前的時間 @property(nonatomic,assign) long currentTime; @property(nonatomic,strong) NSString *macAddre; @property(nonatomic,strong) NSString *macName; -(void)disMainOtaBle; @end
BuleHelp.m
//程序運行后,會自動調(diào)用的檢查藍牙的方法 并掃描藍牙的方法
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
if ([central state] == CBCentralManagerStatePoweredOff) {
NSLog(@"CoreBluetooth BLE hardware is powered off");
}
else if ([central state] == CBCentralManagerStatePoweredOn) {
NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
[self startScan];
}
else if ([central state] == CBCentralManagerStateUnauthorized) {
NSLog(@"CoreBluetooth BLE state is unauthorized");
}
else if ([central state] == CBCentralManagerStateUnknown) {
NSLog(@"CoreBluetooth BLE state is unknown");
}
else if ([central state] == CBCentralManagerStateUnsupported) {
NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
}
}
/*
* 程序運行的時候開始掃描
*/
-(void)startScan{
_periperals = [[NSMutableArray alloc] init];
_deviceList = [[NSMutableArray alloc] init];
//2.利用中心設(shè)備掃描外部設(shè)備
[_centerManager scanForPeripheralsWithServices:nil options:nil];
}
/*
* 停止掃描
*/
-(void)stopScan{
[_centerManager stopScan];
}
/*
* 設(shè)備中可以包含 Device addre地址 放在 key:kCBAdvDataManufacturerData中既可以得到
* 1.硬件開發(fā)工程師 把地址寫入到設(shè)備的廠家信息中。
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSS{
//判斷如果數(shù)組中不包含當前掃描到的外部設(shè)備才保存
if (![_periperals containsObject:peripheral]){
//包扣3種設(shè)備 都需要去搜索
if([peripheral.name containsString:@"TMW012BT"]||[peripheral.name containsString:@"OTA"]){
NSLog(@"DATA: %@", advertisementData);
NSArray *keys = [advertisementData allKeys];
for (int i = 0; i < [keys count]; ++i) {
id key = [keys objectAtIndex: i];
NSString *keyName = (NSString *) key;
NSData *value = [advertisementData objectForKey: key];
if([keyName isEqualToString:@"kCBAdvDataManufacturerData"]){
NSLog(@"value is %@",value);
NSString *result = [self convertDataToHexStr:value];
NSLog(@"reslut is %@",result);
if(result!=nil&&result.length>4){
NSString *d = [result substringFromIndex:4];
NSLog(@"D IS %@",d);
// 小寫
//NSString *lower = [test lowercaseString];
// 大寫
NSString *upper = [d uppercaseString];
_macAddre = [NSString stringWithFormat:@"S/N:%@",upper];
}
}
if([keyName isEqualToString:@"kCBAdvDataLocalName"]){
NSString *aStr= (NSString*)value;
NSLog(@"astr is %@",aStr);
_macName = aStr;
}
}
_deviceModel = [DeviceModel new];
_deviceModel.deviceName = _macName;
//藍牙地址
_deviceModel.deviceAddre = _macAddre;
int rssi = [RSS intValue];
NSString *range = [NSString stringWithFormat:@"%d",rssi];
NSString *rs = [NSString stringWithFormat:@"RSSI %@dBm",range];
//添加到里面
[self.periperals addObject:peripheral];
_deviceModel.deviceRssi = rs;
[_deviceList addObject:_deviceModel];
}
}
}
//解析廣播里面的數(shù)據(jù)
-(void)getAdvertisementData:(NSDictionary<NSString *,id> *) advertisementData{
NSArray *keys = [advertisementData allKeys];
for (int i = 0; i < [keys count]; ++i) {
id key = [keys objectAtIndex: i];
NSString *keyName = (NSString *) key;
NSObject *value = [advertisementData objectForKey: key];
if([keyName isEqualToString:@"kCBAdvDataManufacturerData"]){
printf(" key: %s\n", [keyName cStringUsingEncoding: NSUTF8StringEncoding]);
NSString *values = (NSString *) value;
NSLog(@"values is %@",values);
}
}
}
/*
* 連接藍牙設(shè)備給外部調(diào)用的方法
* 傳入的是相對應的行數(shù)
*/
-(void)contentBlue:(int) row{
[_centerManager connectPeripheral:_periperals[row] options:nil];
}
-(void)disContentBle{
//關(guān)鍵的斷開藍牙 通知也要停止掉
if((_peripheral!=nil && _sendtempcharateristic!=nil)){
[_peripheral setNotifyValue:NO forCharacteristic:_sendtempcharateristic];
[self disconnectPeripheral:_peripheral];
}
}
/*
* 斷開ota的 連接
*/
-(void)disContentOtaBle{
if(_peripheral!=nil && _sendotacharateristic!=nil){
[_peripheral setNotifyValue:NO forCharacteristic:_sendotacharateristic];
[self disconnectPeripheral:_peripheral];
}
}
-(void)disMainOtaBle{
if(_peripheral!=nil){
[self disconnectPeripheral:_peripheral];
}
}
- (void) disconnectPeripheral:(CBPeripheral*)peripheral
{
[_centerManager cancelPeripheralConnection:peripheral];
}
//連接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
NSLog(@"連接成功");
if(peripheral!=nil){
//停止掃描 這個用于自動連接的時候
[_centerManager stopScan];
//設(shè)備名稱
_deviceName = peripheral.name;
_selectperipheral = peripheral;
peripheral.delegate = self;
//再去掃描服務
[peripheral discoverServices:nil];
}
}
//連接失敗
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
NSLog(@"連接失敗,失敗原因:%@",error);
NSString *disContentBlue = @"discontentblue";
NSDictionary *blueDiscontent = [NSDictionary dictionaryWithObject:disContentBlue forKey:@"disconnect"];
//發(fā)送廣播 連接失敗
[[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];
}
//斷開連接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
NSLog(@"斷開連接");
NSString *disContentBlue = @"discontentblue";
//_blueiscon = @"Disconnect";
NSDictionary *blueDiscontent = [NSDictionary dictionaryWithObject:disContentBlue forKey:@"disconnect"];
//發(fā)送廣播 連接失敗
[[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];
}
//只要掃描到服務就會調(diào)用,其中的外設(shè)就是服務所在的外設(shè)
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
if (error){
NSLog(@"掃描服務出現(xiàn)錯誤,錯誤原因:%@",error);
}else{
//獲取外設(shè)中所掃描到的服務
for (CBService *service in peripheral.services){
//拿到需要掃描的服務,例如FFF0 比如打印溫度數(shù)據(jù)
//把所有的service打印出來
//從需要的服務中查找需要的特征
//從peripheral的services中掃描特征
[peripheral discoverCharacteristics:nil forService:service];
}
}
}
//只要掃描到特征就會調(diào)用,其中的外設(shè)和服務就是特征所在的外設(shè)和服務
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(nonnull CBService *)service error:(nullable NSError *)error{
if(error){
NSLog(@"掃描特征出現(xiàn)錯誤,錯誤原因:%@",error);
}else{
//遍歷特征,拿到需要的特征進行處理
for (CBCharacteristic *characteristic in service.characteristics){
NSLog(@"characteristic is %@",characteristic.UUID);
//如果是溫度數(shù)據(jù)處理
if([characteristic.UUID isEqual:BOOT_TEMPVALUE_UUID]){
//將全部的特征信息打印出來
_isconnected = true;
_peripheral = peripheral;
_sendtempcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//如果是ota進行ota升級
else if([characteristic.UUID isEqual:BOOT_OTA_WIRTE_UUID]){
_peripheral = peripheral;
_sendotacharateristic = characteristic;
//設(shè)置通知
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
_isOta = TRUE;
[_userDefaults saveOta:_isOta];
//[_ setBool:_isOta forKey:@"isOTA"];
NSString *s = @"OTA";
NSDictionary *tempOta = [NSDictionary dictionaryWithObject:s forKey:@"ota"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tempOTA" object:nil userInfo:tempOta];
}
//CAL
else if([characteristic.UUID isEqual:BOOT_CAL_UUID]){
_sendcalsetcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//interval time
else if([characteristic.UUID isEqual:BOOT_INTERVALTIME_UUID]){
_sendintervaltimecharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//Tempunit
else if([characteristic.UUID isEqual:BOOT_TEMPUNIT_UUID]){
_sendtempunitcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//DFU
else if([characteristic.UUID isEqual:BOOT_DFU_UUID]){
_senddfucharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//發(fā)送字符串'CR'清除機子上的最大值(3個字節(jié))
else if([characteristic.UUID isEqual:BOOT_CRSTRING_UUID]){
_senddcrstrateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
//發(fā)送字符串'PD'機子關(guān)機(3個字節(jié))
else if([characteristic.UUID isEqual:BOOT_OUTSTRING_UUID]){
_senddoutstrateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
else{
}
}
}
}
/*
設(shè)置通知
*/
-(void)notifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
[_centerManager stopScan];
}
/*
取消通知
*/
-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral
characteristic:(CBCharacteristic *)characteristic{
[peripheral setNotifyValue:NO forCharacteristic:characteristic];
}
/*
接收數(shù)據(jù)解析
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
//是否為Ota
if(!self.isSendOta){
if(self.readtempcharater == characteristic){
NSString *tmpData = [self.cmUtil getTempTMWData:characteristic];
if(tmpData!=nil){
//開始處理數(shù)據(jù)
NSArray *data = [tmpData componentsSeparatedByString:@","];
TmpModel *tp = [[TmpModel alloc] init];
tp.tmp = data[0];
tp.max = data[1];
tp.unit = data[2];
//電量
tp.bat = data[3];
NSDictionary *tempDict = [NSDictionary dictionaryWithObject:tp forKey:@"tempData"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tempNofiction" object:nil userInfo:tempDict];
if([tp.bat isEqual:@"1"]){
//低電量廣播
NSDictionary *LowDict = [NSDictionary dictionaryWithObject:tp forKey:@"lowData"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"lowNofiction" object:nil userInfo:LowDict];
}
}
}
}
//======================寫入數(shù)據(jù)區(qū)塊========================//
/*
寫入發(fā)送時間
*/
-(void)writeIntervalTime:(NSString *)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendtimecharater!=nil){
[self writeData:value forCharacteristic:self.sendtimecharater periperalData:periperal];
}
}
/*
寫入溫度單位
*/
-(void)writeTmpUnit:(NSString*)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendunitcharater!=nil){
[self writeData:value forCharacteristic:self.sendunitcharater periperalData:periperal];
}
}
/*
寫入Cal值
*/
-(void)writeCalValue:(NSString *)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendcalcharater!=nil){
[self writeData:value forCharacteristic:self.sendcalcharater periperalData:periperal];
}
}
/*
發(fā)送Ota使得設(shè)備進入Ota
*/
-(void)writeDfuValue:(NSString *)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.senddfucharater!=nil){
[self writeData:value forCharacteristic:self.senddfucharater periperalData:periperal];
}
}
/*
發(fā)送Max Temp實現(xiàn)清零選項
*/
-(void)writeClearValue:(NSString *)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendclearcharater!=nil){
[self writeData:value forCharacteristic:self.sendclearcharater periperalData:periperal];
}
}
/*
發(fā)送關(guān)機選項實現(xiàn)遠程開關(guān)機
*/
-(void)writeCloseValue:(NSString *)value periperalData:(CBPeripheral*)periperal{
if(value!=nil&&periperal!=nil&&self.sendclosecharater!=nil){
[self writeData:value forCharacteristic:self.sendclosecharater periperalData:periperal];
}
}
/*
所有寫入的數(shù)據(jù)處理
*/
-(void)writeData:(NSString *)value forCharacteristic:(CBCharacteristic *)characteristic periperalData:(CBPeripheral*)periperal{
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
if(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
[periperal writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[periperal writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
此篇文章闡述到這,基本BLE藍牙開發(fā)實現(xiàn)都詳細的描述了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
iOS開發(fā)中UITabBarController的使用示例
這篇文章主要介紹了iOS開發(fā)中UITabBarController的使用示例,代碼基于Objective-C進行演示,需要的朋友可以參考下2015-09-09
如何實現(xiàn)IOS_SearchBar搜索欄及關(guān)鍵字高亮
本文通過實例代碼演示如何實現(xiàn)IOS搜索欄及搜索關(guān)鍵字高亮,效果很棒,小編覺得對大家的學習會很有幫助,現(xiàn)在分享給大家,有需要的可以參考學習。2016-08-08
iOS開發(fā)使用UITableView制作N級下拉菜單的示例
這篇文章主要介紹了iOS開發(fā)使用UITableView制作N級下拉菜單的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01

