您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關IOS如何開發實現Ble藍牙,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
主藍牙類文件.h主藍牙類文件.mUUID文件藍牙列表展示的文件
一:引入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//藍牙的設備搜索顯示在列表中@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;//設備列表@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;//是否發送數據@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;//發送溫度數據@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;//寫入mute alarm-(void)writeMuteAlarm:(NSString *)value;//寫入CR CLERVULE-(void)writeClearCR:(NSString *)value;//寫入interval time-(void)writeIntervalTime:(NSString *)value;//寫入cal set-(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 (^) (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;//是否是第一次連接設備@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
//程序運行后,會自動調用的檢查藍牙的方法 并掃描藍牙的方法- (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.利用中心設備掃描外部設備 [_centerManager scanForPeripheralsWithServices:nil options:nil];}/* * 停止掃描 */-(void)stopScan{ [_centerManager stopScan];}
/* * 設備中可以包含 Device addre地址 放在 key:kCBAdvDataManufacturerData中既可以得到 * 1.硬件開發工程師 把地址寫入到設備的廠家信息中。 */- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSS{ //判斷如果數組中不包含當前掃描到的外部設備才保存 if (![_periperals containsObject:peripheral]){ //包扣3種設備 都需要去搜索 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]; } }}
//解析廣播里面的數據-(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); } }}
/* * 連接藍牙設備給外部調用的方法 * 傳入的是相對應的行數 */-(void)contentBlue:(int) row{ [_centerManager connectPeripheral:_periperals[row] options:nil];}-(void)disContentBle{ //關鍵的斷開藍牙 通知也要停止掉 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]; //設備名稱 _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"]; //發送廣播 連接失敗 [[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"]; //發送廣播 連接失敗 [[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];}
//只要掃描到服務就會調用,其中的外設就是服務所在的外設- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{ if (error){ NSLog(@"掃描服務出現錯誤,錯誤原因:%@",error); }else{ //獲取外設中所掃描到的服務 for (CBService *service in peripheral.services){ //拿到需要掃描的服務,例如FFF0 比如打印溫度數據 //把所有的service打印出來 //從需要的服務中查找需要的特征 //從peripheral的services中掃描特征 [peripheral discoverCharacteristics:nil forService:service]; } }}
//只要掃描到特征就會調用,其中的外設和服務就是特征所在的外設和服務- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(nonnull CBService *)service error:(nullable NSError *)error{ if(error){ NSLog(@"掃描特征出現錯誤,錯誤原因:%@",error); }else{ //遍歷特征,拿到需要的特征進行處理 for (CBCharacteristic *characteristic in service.characteristics){ NSLog(@"characteristic is %@",characteristic.UUID); //如果是溫度數據處理 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; //設置通知 [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]; } //發送字符串'CR'清除機子上的最大值(3個字節) else if([characteristic.UUID isEqual:BOOT_CRSTRING_UUID]){ _senddcrstrateristic = characteristic; [peripheral setNotifyValue:YES forCharacteristic:characteristic]; } //發送字符串'PD'機子關機(3個字節) else if([characteristic.UUID isEqual:BOOT_OUTSTRING_UUID]){ _senddoutstrateristic = characteristic; [peripheral setNotifyValue:YES forCharacteristic:characteristic]; } else{ } } }}
/* 設置通知 */-(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];}
/* 接收數據解析 */- (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){ //開始處理數據 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]; } } } }
//======================寫入數據區塊========================///* 寫入發送時間 */-(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]; }}/* 發送Ota使得設備進入Ota */-(void)writeDfuValue:(NSString *)value periperalData:(CBPeripheral*)periperal{ if(value!=nil&&periperal!=nil&&self.senddfucharater!=nil){ [self writeData:value forCharacteristic:self.senddfucharater periperalData:periperal]; }}/* 發送Max Temp實現清零選項 */-(void)writeClearValue:(NSString *)value periperalData:(CBPeripheral*)periperal{ if(value!=nil&&periperal!=nil&&self.sendclearcharater!=nil){ [self writeData:value forCharacteristic:self.sendclearcharater periperalData:periperal]; }}/* 發送關機選項實現遠程開關機 */-(void)writeCloseValue:(NSString *)value periperalData:(CBPeripheral*)periperal{ if(value!=nil&&periperal!=nil&&self.sendclosecharater!=nil){ [self writeData:value forCharacteristic:self.sendclosecharater periperalData:periperal]; }}/* 所有寫入的數據處理 */-(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]; }}
關于“IOS如何開發實現Ble藍牙”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。