After watching these, dachang is not a dream!!

1. This post explains how to develop Ble Bluetooth. Some common services in Bluetooth, scanning, and linking;

  • Main Bluetooth class file.h
  • Main Bluetooth class file. M
  • UUID file
  • Bluetooth list shows files

One: the introduction of Ble bluetooth framework < > CoreBluetooth/CoreBluetooth. H

BuleHelp.h

# import < Foundation/Foundation. H > # import / / import bluetooth framework < 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 // Bluetooth device search is displayed in the list @property (nonatomic, strong) NSMutableArray <CBPeripheral*>*periperals; // attach peripheral @property(nonatomic,strong) CBPeripheral *peripheral; // attach 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; @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; @property (nonatomic,strong) CBCharacteristic *sendotacharateristic; Data / / @ / / high/low temperature property (nonatomic, strong) CBCharacteristic * sendhighalarmcharateristic; // //@property (nonatomic,strong) CBCharacteristic *sendlowalarmcharateristic; //ota @property (nonatomic,strong) CBCharacteristic *senddfucharateristic; // Send the string 'CR' to clear the maximum value on the machine (3 bytes) @property (nonatomic,strong) CBCharacteristic * sendDCrstrateristic; // Send string 'PD' machine off (3 bytes) @property (nonatomic,strong) CBCharacteristic * sendDOutstrateristic; / / mute @ 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; / / / < = = = = = = = = = = = = = = = method block = = = = = = = = = = = = = = = = = = = = = = = > + sharedManager (id); -(NSMutableArray *)getDeviceList; -(NSMutableArray *)getPeriperalList; -(void)startScan; // connect bluetooth -(void)contentBlue:(int) row; // Disconnect bluetooth -(void)disContentBle; // Disconnect OTA's Bluetooth connection -(void)disContentOtaBle; // writeTempUnit -(void)writeTempUnit (NSString *)value; // writeAlarmSwitch -(void)writeAlarmSwitch:(NSString *)value; // mute alarm -(void)writeMuteAlarm:(NSString *)value; // write CR CLERVULE -(void)writeClearCR:(NSString *)value; // writeIntervalTime -(void)writeIntervalTime:(NSString *)value; // writeCalSet -(void)writeCalSet:(NSString *)value; // write device switch button -(void)writeBluePD:(NSString *)value; //-(void)writeLowAlarm:(NSString *)value; //-(void)writeHighAlarm:(NSString *)value; //OTA firmware upgrade also known as 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; /* * stopScan */ -(void)stopScan; @property(Assign,nonatomic) BOOL isConnected; @property(nonatomic,assign) long currentTime; @property(nonatomic,strong) NSString *macAddre; @property(nonatomic,strong) NSString *macName; -(void)disMainOtaBle; @endCopy the code

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];
    }
}
Copy the code

This article elaborated to this, the basic BLE Bluetooth development implementation is described in detail. Thank you for reading… Don’t forget to “like”, your “like” is the biggest motivation for bloggers to create bluetooth IOS articles in the future.

Have want to interview information or other information can also find me, welcome to consult!

This article will continue to be updated, and you can also send me a message to get information about the interview. If you have any comments and suggestions, please leave a message to me.

IOS partners please pay attention to! If you like, give a thumbs-up! Thank you very much! Thank you very much! Thank you very much!

Original link: blog.csdn.net/qq\_3752344…