這篇文章給大家分享的是有關(guān)IOS中如何開(kāi)發(fā)Ble藍(lán)牙的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
創(chuàng)新互聯(lián)公司是一家專(zhuān)注于做網(wǎng)站、網(wǎng)站設(shè)計(jì)與策劃設(shè)計(jì),吉林網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:吉林等地區(qū)。吉林做網(wǎng)站價(jià)格咨詢(xún):028-86922220
如何開(kāi)發(fā)Ble藍(lán)牙。在藍(lán)牙中的一些常見(jiàn)服務(wù),掃描,以及鏈接;
主藍(lán)牙類(lèi)文件.h
主藍(lán)牙類(lèi)文件.m
UUID文件
藍(lán)牙列表展示的文件
一:引入Ble藍(lán)牙的框架
BuleHelp.h
#import//導(dǎo)入藍(lán)牙框架 #import #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 *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; //斷開(kāi)藍(lán)牙 -(void)disContentBle; //斷開(kāi)ota的藍(lán)牙連接 -(void)disContentOtaBle; //溫度符號(hào) -(void)writeTempUnit:(NSString *)value; //寫(xiě)入報(bào)警開(kāi)關(guān) -(void)writeAlarmSwitch:(NSString *)value; //寫(xiě)入mute alarm -(void)writeMuteAlarm:(NSString *)value; //寫(xiě)入CR CLERVULE -(void)writeClearCR:(NSString *)value; //寫(xiě)入interval time -(void)writeIntervalTime:(NSString *)value; //寫(xiě)入cal set -(void)writeCalSet:(NSString *)value; //寫(xiě)入設(shè)備的開(kāi)關(guān)按鈕 -(void)writeBluePD:(NSString *)value; //寫(xiě)入低溫報(bào)警 //-(void)writeLowAlarm:(NSString *)value; // ////寫(xiě)入高溫報(bào)警 //-(void)writeHighAlarm:(NSString *)value; //OTA固件升級(jí) 又稱(chēng)為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í)候開(kāi)始掃描 */ -(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.硬件開(kāi)發(fā)工程師 把地址寫(xiě)入到設(shè)備的廠家信息中。 */ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary*)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); // 小寫(xiě) //NSString *lower = [test lowercaseString]; // 大寫(xiě) 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*) 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)鍵的斷開(kāi)藍(lán)牙 通知也要停止掉 if((_peripheral!=nil && _sendtempcharateristic!=nil)){ [_peripheral setNotifyValue:NO forCharacteristic:_sendtempcharateristic]; [self disconnectPeripheral:_peripheral]; } } /* * 斷開(kāi)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è)備名稱(chēng) _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]; }
//斷開(kāi)連接 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{ NSLog(@"斷開(kāi)連接"); 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打印出來(lái) //從需要的服務(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]){ //將全部的特征信息打印出來(lái) _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){ //開(kāi)始處理數(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]; } } } }
//======================寫(xiě)入數(shù)據(jù)區(qū)塊========================// /* 寫(xiě)入發(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]; } } /* 寫(xiě)入溫度單位 */ -(void)writeTmpUnit:(NSString*)value periperalData:(CBPeripheral*)periperal{ if(value!=nil&&periperal!=nil&&self.sendunitcharater!=nil){ [self writeData:value forCharacteristic:self.sendunitcharater periperalData:periperal]; } } /* 寫(xiě)入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)程開(kāi)關(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]; } } /* 所有寫(xiě)入的數(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中如何開(kāi)發(fā)Ble藍(lán)牙”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!