溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

IOS如何開發(fā)實(shí)現(xiàn)Ble藍(lán)牙

發(fā)布時(shí)間:2021-09-28 10:07:36 來源:億速云 閱讀:148 作者:小新 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)IOS如何開發(fā)實(shí)現(xiàn)Ble藍(lán)牙,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

主藍(lán)牙類文件.h主藍(lán)牙類文件.mUUID文件藍(lán)牙列表展示的文件

一:引入Ble藍(lán)牙的框架<CoreBluetooth/CoreBluetooth.h>

BuleHelp.h

#import <Foundation/Foundation.h>//導(dǎo)入藍(lán)牙框架#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//藍(lán)牙的設(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;//是否進(jìn)行ota升級(jí)@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;//時(shí)間格式化@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'清除機(jī)子上的最大值(3個(gè)字節(jié))@property (nonatomic,strong) CBCharacteristic *senddcrstrateristic;//發(fā)送字符串'PD'機(jī)子關(guān)機(jī)(3個(gè)字節(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;//連接藍(lán)牙-(void)contentBlue:(int) row;//斷開藍(lán)牙-(void)disContentBle;//斷開ota的藍(lán)牙連接-(void)disContentOtaBle;//溫度符號(hào)-(void)writeTempUnit:(NSString *)value;//寫入報(bào)警開關(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;//寫入低溫報(bào)警//-(void)writeLowAlarm:(NSString *)value;//////寫入高溫報(bào)警//-(void)writeHighAlarm:(NSString *)value;//OTA固件升級(jí) 又稱為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;//當(dāng)前的時(shí)間@property(nonatomic,assign) long currentTime;@property(nonatomic,strong) NSString *macAddre;@property(nonatomic,strong) NSString *macName;-(void)disMainOtaBle;@end

BuleHelp.m

//程序運(yùn)行后,會(huì)自動(dòng)調(diào)用的檢查藍(lán)牙的方法 并掃描藍(lán)牙的方法- (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"); }}

/* * 程序運(yùn)行的時(shí)候開始掃描 */-(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ù)組中不包含當(dāng)前掃描到的外部設(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;   //藍(lán)牙地址   _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);  } }}

/* * 連接藍(lán)牙設(shè)備給外部調(diào)用的方法 * 傳入的是相對(duì)應(yīng)的行數(shù) */-(void)contentBlue:(int) row{ [_centerManager connectPeripheral:_periperals[row] options:nil];}-(void)disContentBle{ //關(guān)鍵的斷開藍(lá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){  //停止掃描 這個(gè)用于自動(dòng)連接的時(shí)候  [_centerManager stopScan];  //設(shè)備名稱  _deviceName = peripheral.name;  _selectperipheral = peripheral;  peripheral.delegate = self;  //再去掃描服務(wù)  [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];}

//只要掃描到服務(wù)就會(huì)調(diào)用,其中的外設(shè)就是服務(wù)所在的外設(shè)- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ if (error){  NSLog(@"掃描服務(wù)出現(xiàn)錯(cuò)誤,錯(cuò)誤原因:%@",error); }else{  //獲取外設(shè)中所掃描到的服務(wù)  for (CBService *service in peripheral.services){   //拿到需要掃描的服務(wù),例如FFF0 比如打印溫度數(shù)據(jù)   //把所有的service打印出來   //從需要的服務(wù)中查找需要的特征   //從peripheral的services中掃描特征   [peripheral discoverCharacteristics:nil forService:service];  } }}

//只要掃描到特征就會(huì)調(diào)用,其中的外設(shè)和服務(wù)就是特征所在的外設(shè)和服務(wù)- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(nonnull CBService *)service error:(nullable NSError *)error{ if(error){  NSLog(@"掃描特征出現(xiàn)錯(cuò)誤,錯(cuò)誤原因:%@",error); }else{  //遍歷特征,拿到需要的特征進(jìn)行處理  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進(jìn)行ota升級(jí)   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'清除機(jī)子上的最大值(3個(gè)字節(jié))   else if([characteristic.UUID isEqual:BOOT_CRSTRING_UUID]){    _senddcrstrateristic = characteristic;    [peripheral setNotifyValue:YES forCharacteristic:characteristic];   }   //發(fā)送字符串'PD'機(jī)子關(guān)機(jī)(3個(gè)字節(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ā)送時(shí)間 */-(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è)備進(jìn)入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實(shí)現(xiàn)清零選項(xiàng) */-(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)機(jī)選項(xiàng)實(shí)現(xiàn)遠(yuǎn)程開關(guān)機(jī) */-(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]; }}

關(guān)于“IOS如何開發(fā)實(shí)現(xiàn)Ble藍(lán)牙”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI