IOS Ble蓝牙开发实现方法

本篇博文阐述如何开发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

//蓝牙的设备搜索显示在列表中

@property (nonatomic, span) NSMutableArray <CBPeripheral*>*periperals;

//连接peripheral

@property(nonatomic,span) CBPeripheral *peripheral;

//连接peripheral

@property(nonatomic,span) CBPeripheral *selectperipheral;

//中心管理者

@property (nonatomic, span) CBCentralManager *centerManager;

@property (nonatomic,span) DeviceModel *deviceModel;

//设备列表

@property (nonatomic,span) NSMutableArray *deviceList;

@property (nonatomic,span) NSMutableArray *commandArray;

//是否进行ota升级

@property (nonatomic) BOOL isOta;

@property (nonatomic) BOOL isWritePacketDataSuccess;

@property (span,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 (span,nonatomic) NSString *siliconIDString;

/*!

* @property siliconRevString

*

* @discussion silicon rev from the device response

*

*/

@property (span,nonatomic) NSString *siliconRevString;

//是否发送数据

@property (nonatomic) BOOL isSendData;

@property (span,nonatomic) CommonUtil *commonUtil;

@property (span,nonatomic) TempDB *tempDB;

@property (span,nonatomic) NSDate *currentDate;

//时间格式化

@property(span,nonatomic) NSDateFormatter *dateformatter;

@property(span,nonatomic) NSString *deviceName;

//@property (nonatomic,span) NSUserDefaults *userDefaults;

@property (nonatomic,span) CommonUserDefaults *userDefaults;

//发送温度数据

@property (nonatomic,span) CBCharacteristic *sendtempcharateristic;

//发送OTA数据

@property (nonatomic,span) CBCharacteristic *sendotacharateristic;

//高/低温度数据

//@property (nonatomic,span) CBCharacteristic *sendhighalarmcharateristic;

//

//@property (nonatomic,span) CBCharacteristic *sendlowalarmcharateristic;

//ota

@property (nonatomic,span) CBCharacteristic *senddfucharateristic;

//发送字符串'CR'清除机子上的最大值(3个字节)

@property (nonatomic,span) CBCharacteristic *senddcrstrateristic;

//发送字符串'PD'机子关机(3个字节)

@property (nonatomic,span) CBCharacteristic *senddoutstrateristic;

//静音

@property (span,nonatomic) CBCharacteristic *sendmutealarmcharateristic;

//calset

@property(span,nonatomic) CBCharacteristic *sendcalsetcharateristic;

//intervaltime

@property(span,nonatomic) CBCharacteristic *sendintervaltimecharateristic;

//alarmswitch

@property(span,nonatomic) CBCharacteristic *sendalarmswitchcharateristic;

//tempunit

@property(span,nonatomic) CBCharacteristic *sendtempunitcharateristic;

@property(span,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,span) NSString *macAddre;

@property(nonatomic,span) 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];

}

}

此篇文章阐述到这,基本BLE蓝牙开发实现都详细的描述了。

以上是 IOS Ble蓝牙开发实现方法 的全部内容, 来源链接: utcz.com/z/349402.html

回到顶部