IOS 蓝牙设备断开时间内进行自动链接

一:IOS Ble蓝牙设备自动链接蓝牙的功能需求
二: 主要分为以下几个逻辑点:
1.把主蓝牙列表MAC地址存储到详情界面
2.把链接成功的服务(peripheral)列表调用如:self.deviceModel.peripheral = peripheral;
3.当设备关闭断开的时候,进行时间的运算,判断处理是否进行自动链接

1.设备的蓝牙列表总界面
DeviceViewController.h

#import <UIKit/UIKit.h>
#import "BaseTableViewController.h"
#import "DeviceCell.h"
#import "DeviceView.h"
#import "DeviceModel.h"
#import "BlueUtil.h"
#import "CommonDefaults.h"
#import "BTAlertController.h"
#import "BlueTempViewController.h"
#import "OtaViewController.h"
//#import "WJProgress.h"

@interface DeviceViewController : BaseTableViewController
//空白布局文件
@property(strong,nonatomic) DeviceView *deviceView;
//蓝牙列表
@property (nonatomic,strong) NSMutableArray *deviceList;

@property(strong,nonatomic) DeviceModel *deviceModel;
// 扫描到的外围设备
//@property (nonatomic,strong ) NSMutableArray <CBPeripheral*>*peripheralList;
@property (nonatomic,strong ) NSMutableArray *peripheralList;
//获取设备定时器
@property(strong,nonatomic) NSTimer *deviceTimer;

@property(strong,nonatomic) BlueUtil *bleUtil;

@property(strong,nonatomic) CommonDefaults *cmDefaults;

@end

二:蓝牙列表总界面
DeviceViewController.m

//
//  DeviceViewController.m
//  BWProject
//
//  Created by rnd on 2018/6/28.
//  Copyright © 2018年 Radiance Instruments Ltd. All rights reserved.
//

#import "DeviceViewController.h"
//蓝牙的的两个代理
@interface DeviceViewController ()<UITableViewDelegate,UITableViewDataSource>
@end

@implementation DeviceViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //定义函数initData
    [self initData];
}
//导航栏中间对齐
- (void)customContentView{
    UIColor *commonBlue = [self.commonUtil stringToColor:@"#333333"];
    [self.navigationController.navigationBar setBarTintColor:commonBlue];
    self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
    self.navigationItem.title = @"BLE";
    
    //创建下啦刷新
    NSString *dropscan = NSLocalizedString(@"dropscan", nil);
    UIRefreshControl *rc = [[UIRefreshControl alloc] init];
    rc.attributedTitle = [[NSAttributedString alloc] initWithString:dropscan];
    [rc addTarget:self action:@selector(redreshTableView) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = rc;
}


-(void)initData{
    //蓝牙设备类
    self.bleUtil  = [BlueUtil sharedManager];
    [self getDeviceModel];
    [self getDeviceList];
    [self getPeripheralList];
  
    self.tableView.delegate  = self;
    self.tableView.dataSource = self;
    
    //小技巧,用了之后不会出现多余的Cell
    UIView *view = [[UIView alloc] init];
    self.tableView.tableFooterView = view;
    
    //设备定时器时间,如果等于null就每隔2秒钟扫描一次
    if(_deviceTimer==nil){
        _deviceTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(deviceTime) userInfo:nil repeats:YES];
    }
}

/*
    程序加载的时候调用
 */
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    if(_deviceList.count>0&&_peripheralList.count>0){
        //可变数组对象
        [_deviceList removeAllObjects];
        [_peripheralList removeAllObjects];
        //重新加载数据
        [self.tableView reloadData];
    }
    
    if (self.refreshControl.refreshing) {
        //TODO: 已经在刷新数据了
        //NSLog(@"12233");
    } else {
        NSLog(@"y is %f",self.tableView.contentOffset.y);
        if (self.tableView.contentOffset.y == -64.0) {
            [UIView animateWithDuration:0.25
                                  delay:0
            options:UIViewAnimationOptionBeginFromCurrentState
                             animations:^(void){
                                 self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
                             } completion:^(BOOL finished){
                                 [self.refreshControl beginRefreshing];
                                 [self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];
                             }];
        }
    }
}

//设备布局文件
-(DeviceView *)getDeviceView{
    if(self.deviceView==nil){
        self.deviceView = [[DeviceView alloc] init];
    }
    return self.deviceView;
}
//设备蓝牙列表初始化
-(NSMutableArray*)getDeviceList{
    if(self.deviceList==nil){
        self.deviceList=[NSMutableArray array];
    }
    return self.deviceList;
}
//外围蓝牙设备初始化
-(NSMutableArray*)getPeripheralList{
    if(self.peripheralList==nil){
        self.peripheralList = [NSMutableArray array];
    }
    return self.peripheralList;
}

-(DeviceModel*)getDeviceModel{
    if(self.deviceModel==nil){
        self.deviceModel = [[DeviceModel alloc] init];
    }
    return self.deviceModel;
}

//获取设备连接的数据
-(void)deviceTime{
    self.deviceList = [self.bleUtil getDeviceLists];
    self.peripheralList = [self.bleUtil getPeriperalLists];
    if(self.deviceList.count>0){
        [self.tableView reloadData];
    }
}

//tableview的行数
#pragma mark tableView
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.deviceList.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellIdentifiter = @"DeviceCellIdentifiter";
    DeviceCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifiter];
    if (cell == nil) {
        cell = [[DeviceCell alloc] initWithStyle:UITableViewCellStyleDefault
                                 reuseIdentifier:cellIdentifiter];
    }
  //蓝牙列表行数是否大于0
    if([self.deviceList count]>0){
        NSUInteger row = [indexPath row];
        if(row<self.deviceList.count){
            _deviceModel = [_deviceList objectAtIndex:indexPath.row];
            cell.mDeviceNameLb.text = self.deviceModel.deviceName;
            cell.mDeviceAddreLb.text = self.deviceModel.deviceAddre;
        }
    }
    return cell;
}

#pragma tableView的点击事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifiter = @"DeviceCellIdentifiter";
    DeviceCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifiter];
    if (cell == nil) {
        cell = [[DeviceCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifiter];
    }
    
    if(self.deviceList.count>0){
        NSString *contentTips = @"Connect Tips";
        NSString *multiple = @"Cancel";
        NSString *single = @"Connect";
        //该方法响应列表中行的点击事件
        NSString *bleSelected=@"";
        //indexPath.row得到选中的行号,提取出在数组中的内容。
        BTAlertController *alertController = [BTAlertController alertControllerWithTitle:contentTips message:bleSelected preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction *noAction = [UIAlertAction actionWithTitle:multiple style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
        }];
        
        UIAlertAction *yesAction = [UIAlertAction actionWithTitle:single style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
            //连接第一个扫描到的外设
            NSUInteger row = [indexPath row];
            int rows =(int)row;
            self.deviceModel = [self.deviceList objectAtIndex:indexPath.row];
            //[self.cmDefaults saveMacAdder:self.deviceModel.deviceAddre];
            //存储地址
            [[CommonDefaults shared] saveMacAdder:self.deviceModel.deviceAddre];
            //如果是为OTA的话
            if([self.deviceModel.deviceName containsString:@"update"]){
                [[BlueUtil sharedManager] contentBlue:rows];
                OtaViewController *otaView = [[OtaViewController alloc] init];
                otaView.title = @"OTA UpGrade";
                [self.navigationController pushViewController:otaView animated:YES];
            }else{
                //连接蓝牙
                [[BlueUtil sharedManager] contentBlue:rows];
                BlueTempViewController *bluetempView = [[BlueTempViewController alloc] init];
                bluetempView.title = @"Temperature";
               
                [self.navigationController pushViewController:bluetempView animated:YES];
            }
        }];
        
        [alertController addAction:noAction];
        [alertController addAction:yesAction];
        [self presentViewController:alertController animated:true completion:nil];
        
    }
}

//定义列的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 90;
}

//读取刷新TableView
-(void)redreshTableView{
    if(self.refreshControl.refreshing){
        self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refresh"];
        
        if(_deviceList!=nil&&_deviceList.count>0){
            [_deviceList removeAllObjects];
        }
        
        if(_peripheralList.count>0&&_peripheralList!=nil){
            [_peripheralList removeAllObjects];
        }
        //扫描蓝牙
        [self.bleUtil startScan];
        [self.refreshControl endRefreshing];
        self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Down Refresh"];
        //扫描
        [self.tableView reloadData];
    }
}


//用完之后需要关闭掉
-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [[BlueUtil sharedManager] stopScan];
}


@end

三:蓝牙服务界面:

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "DeviceModel.h"
#import "Constants.h"
#import "BlueTempModel.h"
#import "BWTmpDB.h"
#import "TmpModel.h"
#import "MBProgressHUD.h"
#import "CommonUtil.h"

@interface BlueUtil : NSObject

+ (id)sharedManager;

//颜色转换
@property(nonatomic,strong) CommonUtil *comUtil;

//蓝牙的设备搜索显示在列表中
@property (nonatomic, strong) NSMutableArray <CBPeripheral*>*periperals;// 扫描到的外围设备

//连接peripheral
@property(nonatomic,strong) CBPeripheral *peripheral;

//中心管理者
@property (nonatomic, strong) CBCentralManager *centerManager;

//设备列表
@property(nonatomic,strong) NSMutableArray *deviceList;

@property(nonatomic,strong) BlueTempModel *blueTempModel;

@property(strong,nonatomic) NSMutableArray *tempList;

//所有的charater
@property(nonatomic,strong)CBCharacteristic *readtempcharaterone;

//读取高低温报警值
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterone;
@property(nonatomic,strong)CBCharacteristic *readalarmcharatertwo;
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterthree;
@property(nonatomic,strong)CBCharacteristic *readalarmcharaterfour;

//OTA
@property(nonatomic,strong)CBCharacteristic *sendotacharateristic;

//发送数据进行OTA升级
@property(nonatomic,strong) CBCharacteristic *sendupcharateristic;

//读取单位
@property(nonatomic,strong)CBCharacteristic *readtempunit;

//报警静音
@property(nonatomic,strong) CBCharacteristic *sendmuteswitch;

//自动链接
@property(nonatomic,strong) CBCharacteristic *sendzidswitch;

//设备信息
@property(nonatomic,strong)CBCharacteristic *readdeviceinfo;

//设置路由器账号密码
@property(nonatomic,strong)CBCharacteristic *sendsetarouter;

//传输时间间隔
@property(nonatomic,strong) CBCharacteristic *sendupdatetime;

//设备名字
@property(nonatomic,strong) CBCharacteristic *senddevicename;

//设置服务器地址端口
@property(nonatomic,strong) CBCharacteristic *sendsevername;

//设备
@property (nonatomic,strong) DeviceModel *deviceModel;

//dalao
@property(strong,nonatomic) MBProgressHUD *hud;

-(NSMutableArray *)getDeviceLists;

-(NSMutableArray *)getPeriperalLists;

-(void)contentBlue:(int) row;

-(void)startScan;

-(void)stopScan;

//断开蓝牙
-(void)disContentBle;

-(void)writeUpdateOTA:(NSString*)value;

-(void)writeBlueOTA:(NSString *)value;

-(void)wirteBlueOTAData:(NSData *)value;

//写入温度单位数据
-(void)writeUnitData:(NSString *)value;

//写入静音开关数据
-(void)writeMuteData:(NSString*)value;

//写入自动链接列表
-(void)contentAutoBlue:(CBPeripheral*)peripheral;

-(void)writeAlarmData:(NSString *)value codes:(NSString *)code;

//写入arouter值
-(void)sendARouterData:(NSString*)value;

//写入更新时间值
-(void)sendUpdateData:(NSString*)value;

//写入设备名字
-(void)sendNameData:(NSString*)value;

//写入服务器地址端口值
-(void)sendIPPortData:(NSString*)value;
@end

BlueUtil.m

#import "BlueUtil.h"

@interface BlueUtil()<CBCentralManagerDelegate,CBPeripheralDelegate>

@end


@implementation BlueUtil

+ (id)sharedManager {
    static BlueUtil *sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

-(id)init{
    self = [super init];
    if(self){
        [self getCBCentralManager];//中心管理者
        self.centerManager.delegate = self;
        [self getPeriperals];//链接
        [self getDeviceList];
        [self getDeviceModel];
        //[self getBlueTempModel];
        [self gettempList];
        [self getComUtil];
    }
    return self;
}

-(CommonUtil *)getComUtil{
    if(self.comUtil==nil){
        self.comUtil = [[CommonUtil alloc] init];
    }
    return self.comUtil;
}
//管理中心者
-(CBCentralManager*)getCBCentralManager{
    if(self.centerManager==nil){
        self.centerManager = [[CBCentralManager alloc] init];
    }
    return self.centerManager;
}
//链接的蓝牙
-(NSMutableArray *)getPeriperals{
    if(self.periperals==nil){
        self.periperals = [NSMutableArray array];
    }
    return self.periperals;
}
//获取设备列表
-(NSMutableArray *)getDeviceList{
    if(self.deviceList==nil){
        self.deviceList = [NSMutableArray array];
    }
    return self.deviceList;
}
//获取设备名称,地址样式
-(DeviceModel*)getDeviceModel{
    if(self.deviceModel==nil){
        self.deviceModel = [[DeviceModel alloc] init];
    }
    return self.deviceModel;
}
//获取最大,最小温度状态,报警状态
-(BlueTempModel *)getBlueTempModel{
    if(self.blueTempModel==nil){
        self.blueTempModel = [[BlueTempModel alloc] init];
    }
    return self.blueTempModel;
}
//获取实时温度的列表数据
-(NSMutableArray *)gettempList{
    if(self.tempList==nil){
        self.tempList = [NSMutableArray array];
    }
    return self.tempList;
}

/*
 * 获取设备的list
 */
-(NSMutableArray *)getDeviceLists{
    return self.deviceList;
}

/*
 * 获取设备的periperals
 */
-(NSMutableArray *)getPeriperalLists{
    return self.periperals;
}

#pragma 蓝牙代理 ---
//程序运行后,会自动调用的检查蓝牙的方法 并扫描蓝牙的方法
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    if (@available(iOS 10.0, *)) {
        if ([central state] == CBManagerStatePoweredOff) {
            NSLog(@"CoreBluetooth BLE hardware is powered off");
        }
        else if ([central state] == CBManagerStatePoweredOn) {
            NSLog(@"CoreBluetooth BLE hardware is powered on and ready");
            [self startScan];
        }
        else if ([central state] == CBManagerStateUnauthorized) {
            NSLog(@"CoreBluetooth BLE state is unauthorized");
        }
        else if ([central state] == CBManagerStateUnknown) {
            NSLog(@"CoreBluetooth BLE state is unknown");
        }
        else if ([central state] == CBManagerStateUnsupported) {
            NSLog(@"CoreBluetooth BLE hardware is unsupported on this platform");
        }
    } else {
        // Fallback on earlier versions
    }
}

/*
 * 程序运行的时候开始扫描
 */
-(void)startScan{
    if(self.periperals.count>0){
        [self.periperals removeAllObjects];
    }
    
    if(self.deviceList.count>0){
        [self.deviceList removeAllObjects];
    }
    //利用中心设备扫描外部设备
    [self.centerManager scanForPeripheralsWithServices:nil options:nil];
}

/*
 * 停止扫描
 */
-(void)stopScan{
    [self.centerManager stopScan];
}

/*
 * 连接蓝牙设备给外部调用的方法
 * 传入的是相对应的行数
 */
-(void)contentBlue:(int) row{
    [self.centerManager connectPeripheral:self.periperals[row] options:nil];
}

//断开蓝牙
-(void)disContentBle{
    //关键的断开蓝牙  通知也要停止掉
    if(self.peripheral!=nil){
        if(self.readtempcharaterone!=nil){
            [self.peripheral setNotifyValue:NO forCharacteristic:self.readtempcharaterone];
        }
        
        [self disconnectPeripheral:self.peripheral];
    }
}


//链接外设的列表
- (void) disconnectPeripheral:(CBPeripheral*)peripheral
{
    [self.centerManager cancelPeripheralConnection:peripheral];
}
//中心设备获取外围设备的列表
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSS{
    //NSString *deviceName;
    if (![self.periperals containsObject:peripheral]){
        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:@"kCBAdvDataLocalName"]){
                NSString *aStr= (NSString*)value;
                NSLog(@"astr is %@",aStr);
                
                self.deviceModel = [[DeviceModel alloc] init];
                self.deviceModel.deviceName = aStr;
                self.deviceModel.peripheral = peripheral;
               [self.periperals addObject:peripheral];
               [self.deviceList addObject:self.deviceModel];
            }
            
            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 *upper = [result uppercaseString];
                    self.deviceModel.deviceAddre = [NSString stringWithFormat:@"S/N:%@",upper];
                }
            }
        }
    }
}

//连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    if(peripheral!=nil){
        //停止扫描 这个用于自动连接的时候
        [self.centerManager stopScan];
        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(@"断开连接22");
    NSString *disContentBlue = @"discontentblue";
    NSDictionary *blueDiscontent = [NSDictionary dictionaryWithObject:disContentBlue forKey:@"disconnect"];
    //发送广播 连接失败
    [self.hud hideAnimated:YES];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"disNofiction" object:nil userInfo:blueDiscontent];
}

#pragma mark - CBPeripheralDelegate
//只要扫描到服务就会调用,其中的外设就是服务所在的外设
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    if (error){
        NSLog(@"扫描服务出现错误,错误原因:%@",error);
    }else{
        //获取外设中所扫描到的服务
        for (CBService *service in peripheral.services){
            //把所有的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);
            //发送数据到OTA
            if([characteristic.UUID isEqual:BW_PROJECT_UPDATE_OTA]){
                self.peripheral = peripheral;
                self.sendupcharateristic = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //OTA升级
            else if([characteristic.UUID isEqual:BW_PROJECT_OTA_DATA]){
                self.peripheral = peripheral;
                self.sendotacharateristic = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //所有探头的温度数据
            else if([characteristic.UUID isEqual:BW_PROJECT_TEMP_ONE]){
                self.readtempcharaterone = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //第一个报警值
            else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_ONE]){
                self.readalarmcharaterone = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //第二个报警值
            else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_TWO]){
                self.readalarmcharatertwo = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //第三个报警值
            else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_THREE]){
                self.readalarmcharaterthree = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //第四个报警值
            else if([characteristic.UUID isEqual:BW_PROJECT_ALARM_FOUR]){
                self.readalarmcharaterfour = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //温度单位
            else if([characteristic.UUID isEqual:BW_PROJECT_TEMP_UNIT]){
                self.readtempunit = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //报警静音 此过程只能发送数据 并无读取数据的功能
            else if([characteristic.UUID  isEqual:BW_PROJECT_MUTE_SWITCH]){
                self.sendmuteswitch = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //设备信息
            else if([characteristic.UUID isEqual:BW_PROJECT_DEVICE_INFO])
            {
                self.readdeviceinfo = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //设置路由器
            else if([characteristic.UUID isEqual:BW_PROJECT_AROUTER_DATA]){
                self.sendsetarouter = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //发送时间间隔
            else if([characteristic.UUID isEqual:BW_PROJECT_UPDATE_TIME]){
                self.sendupdatetime = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //修改设备名字
            else if([characteristic.UUID isEqual:BW_PROJECT_DEVICE_NAME]){
                self.senddevicename = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
            //修改设备IP和端口号
            else if([characteristic.UUID isEqual:BW_PROJECT_ADDERPORT_DATA]){
                self.sendsevername = characteristic;
                [peripheral setNotifyValue:YES forCharacteristic:characteristic];
            }
        }
    }
}

//设置通知
-(void)notifyCharacteristic:(CBPeripheral *)peripheral
             characteristic:(CBCharacteristic *)characteristic{
    //设置通知,数据通知会进入:didUpdateValueForCharacteristic方法
    NSLog(@"发现通知!");
    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    [self.centerManager stopScan];
}

//取消通知
-(void)cancelNotifyCharacteristic:(CBPeripheral *)peripheral
                   characteristic:(CBCharacteristic *)characteristic{
    [peripheral setNotifyValue:NO forCharacteristic:characteristic];
}

//接受解析数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{   //第一个探头
    if(characteristic==self.readtempcharaterone){
        NSString *tempdata = [self getTempTMWData:characteristic];
        NSArray *data = [tempdata componentsSeparatedByString:@","];
        NSDictionary *tempDict = [NSDictionary dictionaryWithObject:data forKey:@"tempData"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"tempNofiction" object:nil userInfo:tempDict];
    }
    
    else if(characteristic==self.readalarmcharaterone){
        NSString *alarmdata = [self getTempTMWData:characteristic];
        if(alarmdata!=nil){
            NSArray *data = [alarmdata componentsSeparatedByString:@","];
            NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataOne"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionOne" object:nil userInfo:alarmDict];
        }
    }
    
    else if(characteristic==self.readalarmcharatertwo){
        NSString *alarmdata = [self getTempTMWData:characteristic];
        if(alarmdata!=nil){
            NSArray *data = [alarmdata componentsSeparatedByString:@","];
            NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataTwo"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionTwo" object:nil userInfo:alarmDict];
        }
    }
    
    else if(characteristic==self.readalarmcharaterthree){
        NSString *alarmdata = [self getTempTMWData:characteristic];
        if(alarmdata!=nil){
            NSArray *data = [alarmdata componentsSeparatedByString:@","];
            NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataThree"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionThree" object:nil userInfo:alarmDict];
        }
    }
    
    else if(characteristic==self.readalarmcharaterfour){
        NSString *alarmdata = [self getTempTMWData:characteristic];
        if(alarmdata!=nil){
            NSArray *data = [alarmdata componentsSeparatedByString:@","];
            NSDictionary *alarmDict = [NSDictionary dictionaryWithObject:data forKey:@"alarmDataFour"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"alarmNofictionFour" object:nil userInfo:alarmDict];
        }
    }
    //如果读取到温度的单位
    else if(characteristic==self.readtempunit){
        NSString *tempunit = [self getTempTMWData:characteristic];//1
        NSDictionary *tempDict = [NSDictionary dictionaryWithObject:tempunit forKey:@"tempUnit"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"tempUnitNofiction" object:nil userInfo:tempDict];
    }
    //读取设备信息
    else if(characteristic==self.readdeviceinfo){
        NSString *deviceinfo = [self getTempTMWData:characteristic];
        if(deviceinfo!=nil){
            NSArray *data = [deviceinfo componentsSeparatedByString:@","];
            if([data count]>0){
                if([data count]>4){
                     NSLog(@"astr is %@",data[4]);
                }
            }
            NSDictionary *deviceinfoDict = [NSDictionary dictionaryWithObject:data forKey:@"deviceInfo"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"deviceInfoNofiction" object:nil userInfo:deviceinfoDict];
        }
    }
    //OTA升级的时候
    else if(characteristic==self.sendotacharateristic){
        //接受数据处理
        NSString *data = [self getOTAData:characteristic];
        if(data!=nil){
            //发送所有数据 要在清单中注册该广播
            NSDictionary *otaDict = [NSDictionary dictionaryWithObject:data forKey:@"otaData"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"otaNofiction" object:nil userInfo:otaDict];
        }
    }
}

-(NSString *)getOTAData:(CBCharacteristic *)characteristic{
    NSData *data = characteristic.value;
    return [self convertDataToHexStr:data];
}

-(NSString *)convertDataToHexStr:(NSData *)data
{
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    return string;
}


//解析温度数据
-(NSString *)getTempTMWData:(CBCharacteristic *)characteristic{
    NSData *data = characteristic.value;
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

/*
 写入数据区块
 */
-(void)writeUpdateOTA:(NSString*)value{
    if(self.sendupcharateristic!=nil){
        NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
        NSLog(@"data is:%@",data);
        [self writeOTA:data forCharacteristic:self.sendupcharateristic];
    }
}


-(void)writeBlueOTA:(NSString *)value{
    NSMutableData *data = [self.comUtil dataFromHexString:[value stringByReplacingOccurrencesOfString:@"0x" withString:@""]];
    NSLog(@"data is:%@",data);
    [self writeOTA:data forCharacteristic:self.sendotacharateristic];
}

-(void)wirteBlueOTAData:(NSData *)value{
    [self writeOTA:value forCharacteristic:self.sendotacharateristic];
}

//写入报警值
-(void)writeAlarmData:(NSString *)value codes:(NSString *)code{
    if([code isEqual:@"one"]){
        if(self.readalarmcharaterone!=nil){
            [self writeTempData:value forCharacteristic:self.readalarmcharaterone];
        }
    }else if([code isEqual:@"two"]){
        if(self.readalarmcharatertwo!=nil){
            [self writeTempData:value forCharacteristic:self.readalarmcharatertwo];
        }
    }else if([code isEqual:@"three"]){
        if(self.readalarmcharaterthree!=nil){
            [self writeTempData:value forCharacteristic:self.readalarmcharaterthree];
        }
    }else if([code isEqual:@"four"]){
        if(self.readalarmcharaterfour!=nil){
            [self writeTempData:value forCharacteristic:self.readalarmcharaterfour];
        }
    }
}


//写入温度单位数据
-(void)writeUnitData:(NSString *)value{
    if(self.readtempunit!=nil){
        [self writeTempData:value forCharacteristic:self.readtempunit];
    }
}

//写入静音开关数据
-(void)writeMuteData:(NSString*)value{
    if(self.sendmuteswitch!=nil){
        [self writeTempData:value forCharacteristic:self.sendmuteswitch];
    }
}



//写入Arouter值
-(void)sendARouterData:(NSString*)value{
    if(self.sendsetarouter!=nil){
        [self writeTempData:value forCharacteristic:self.sendsetarouter];
    }
}

//写入更新时间值
-(void)sendUpdateData:(NSString*)value{
    if(self.sendupdatetime!=nil){
        [self writeTempData:value forCharacteristic:self.sendupdatetime];
    }
}

//写入DeviceName值
-(void)sendNameData:(NSString*)value{
    if(self.senddevicename!=nil){
        [self writeTempData:value forCharacteristic:self.senddevicename];
    }
}
//
//写入IP/PORT值
-(void)sendIPPortData:(NSString*)value{
    if(self.sendsevername!=nil){
        [self writeTempData:value forCharacteristic:self.sendsevername];
    }
}

//写入自动链接列表数据
-(void)contentAutoBlue:(CBPeripheral*)peripheral{
    [self.centerManager connectPeripheral:peripheral options:nil];
}

//写入数据
-(void)writeTempData:(NSString *)value forCharacteristic:(CBCharacteristic *)characteristic
{
    NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
    if(characteristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
    {
        [self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
    }else
    {
        [self.peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
    }
}

//写入OTA的区块
-(void)writeOTA:(NSData *)value forCharacteristic:(CBCharacteristic *)characteristic
{
    //is no write bluetooth data
    if(self.sendotacharateristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
    {
        //send phone on bluetooth data
        [self.peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
    }else
    {
        [self.peripheral writeValue:value forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
    }
    NSLog(@"已经向外设%@的特征值%@写入数据",_peripheral.name,characteristic.description);
}


@end

四:蓝牙详情界面:
BlueTempViewController.h

#import <UIKit/UIKit.h>
#import "BaseViewController.h"
#import "DeviceViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import "BlueTempCell.h"
#import "BlueTempView.h"
#import "BlueTempModel.h"
#import "BlueUtil.h"
#import "BleChartController.h"
#import "MBProgressHUD.h"
#import "SettingController.h"
#import "CommonDefaults.h"
#import "AFNetReqest.h"
#import "Download.h"
#import <AudioToolbox/AudioToolbox.h>

@protocol DownloadModelDelegate <NSObject>
@end

@interface BlueTempViewController : BaseViewController

//@property (nonatomic, strong) NSMutableArray <CBPeripheral*>*periperals;// 扫描到的外围设备

@property(strong,nonatomic) CommonDefaults *cmDefaults;

@property(strong,nonatomic) BlueTempView *btView;

@property(strong,nonatomic) BlueTempModel *blueTempModel;

@property(strong,nonatomic) NSMutableArray *tempList;

@property(nonatomic,strong) NSMutableArray *deviceList;//定义列表

@property(nonatomic,strong) NSMutableArray <CBPeripheral*>*peripheralList;//链接的列表

//-(NSMutableArray *)getDeviceLists;
//
//-(NSMutableArray *)getPeriperalLists;

//连接peripheral
@property(nonatomic,strong) CBPeripheral *peripheral;

@property(nonatomic,assign) int cdata;

@property(nonatomic,strong) NSString *oneHigh;

@property(nonatomic,strong) NSString *oneLow;

@property(nonatomic,strong) NSString *twoHigh;

@property(nonatomic,strong) NSString *twoLow;

@property(nonatomic,strong) NSString *threeHigh;

@property(nonatomic,strong) NSString *threeLow;

@property(nonatomic,strong) NSString *fourHigh;

@property(nonatomic,strong) NSString *fourLow;

@property (nonatomic,assign) BOOL isAutoCon;

@property(assign,nonatomic) BOOL isSaveOnce;

@property (nonatomic,strong) NSTimer * deviceTimer;

@property (nonatomic,assign) int times;

//温度单位
@property(nonatomic,strong) NSString *tmpUnit;
//报警状态1
@property(nonatomic,strong) NSString *alamOneText;
//报警状态2
@property(nonatomic,strong) NSString *alamTwoText;
//报警状态3
@property(nonatomic,strong) NSString *alamThreeText;
//报警状态4
@property(nonatomic,strong) NSString *alamFourText;


//温度状态1
@property(nonatomic,strong) NSString *tempOne;
//温度状态2
@property(nonatomic,strong) NSString *tempTwo;
//温度状态3
@property(nonatomic,strong) NSString *tempThree;
//温度状态4
@property(nonatomic,strong) NSString *tempFour;
//设备探头名称1
@property(nonatomic,strong) NSString *probeOneName;
//设备探头名称2
@property(nonatomic,strong) NSString *probeTwoName;
//设备探头名称3
@property(nonatomic,strong) NSString *probeThreeName;
//设备探头名称4
@property(nonatomic,strong) NSString *probeFourName;
//最大温度1
@property(nonatomic,strong) NSString *maxOne;
//最小温度1
@property(nonatomic,strong) NSString *minOne;
//最大温度2
@property(nonatomic,strong) NSString *maxTwo;
//最小温度2
@property(nonatomic,strong) NSString *minTwo;
//最大温度3
@property(nonatomic,strong) NSString *maxThree;
//最小温度3
@property(nonatomic,strong) NSString *minThree;
//最大温度4
@property(nonatomic,strong) NSString *maxFour;
//最小温度4
@property(nonatomic,strong) NSString *minFour;

//设备序列号
@property(nonatomic,strong) NSString *deviceNo;

//固件升级判断逻辑
@property(nonatomic,strong) NSString *deviceInfo;

@property(strong,nonatomic) NSTimer *highTimer;

@property(strong,nonatomic) NSString *highTimerdata;

//获取当前的时间
@property (strong,nonatomic) NSDate *currentDate;

//时间格式化
@property(strong,nonatomic) NSDateFormatter *dateformatter;

@property(nonatomic) long ctime;

@property(strong,nonatomic) MBProgressHUD *hud;

@property(strong,nonatomic) NSString *salNumber;

@property(strong,nonatomic) NSString *arr;

@property(nonatomic,assign) id<DownloadModelDelegate> delegate;

@property(nonatomic,strong) Download *download;

//新增Model
@property(strong,nonatomic) BlueTempModel *bleModel;


@property(strong,nonatomic) NSString *stringdate;

//中心管理者
@property (nonatomic, strong) CBCentralManager *centerManager;

@end

BlueTempViewController.m

//重写返回
- (void)onBackClick{
    self.isAutoCon = FALSE;
    NSString *tips = @"DisConnect Tips";
    NSString *cancel = @"Cancel";
    NSString *ok = @"OK";
    
    BTAlertController *alertController = [BTAlertController alertControllerWithTitle:tips message:@"Do you want to give up  Bluetooth connected" preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *noAction = [UIAlertAction actionWithTitle:cancel style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
    }];
    
    UIAlertAction *yesAction = [UIAlertAction actionWithTitle:ok style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
        //断开蓝牙 结束升级
        [[BlueUtil sharedManager] disContentBle];
        [self.navigationController popViewControllerAnimated:YES];
    }];
    
    [alertController addAction:noAction];
    [alertController addAction:yesAction];
    [self presentViewController:alertController animated:true completion:nil];
}

/*
 断开蓝牙的时候发送广播
 */
-(void)disContentBle:(NSNotification*)notification{
    self.isAutoCon = TRUE;
    //当接受到蓝牙退出的指令之后 不断开界面 需要重新去连接界面
    if(self.deviceTimer==nil){
        self.deviceTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(deviceTime) userInfo:nil repeats:YES];
    }
}

//自动连接蓝牙代码
-(void)deviceTime{
    //自定加1
    self.times++;
    NSString *mac = [[CommonDefaults shared] getMacAdder];
    self.deviceList = [[BlueUtil sharedManager] getDeviceLists];
    self.peripheralList = [[BlueUtil sharedManager] getPeriperalLists];
    //如果不为空的时候
    if(mac!=nil&&self.isAutoCon){
        for(int i=0;i<self.deviceList.count;i++){
            DeviceModel *data = [self.deviceList objectAtIndex:i];
            if([data.deviceAddre isEqual:mac]){
                [[BlueUtil sharedManager] contentAutoBlue:data.peripheral];
            }
        }
    }
    if(self.times>=5){
        NSLog(@"大于了20。。%@",self.deviceTimer);
        NSLog(@"大于了20.。%d",self.times);
        if(self.deviceTimer!=nil){
            [self.deviceTimer invalidate];
            self.deviceTimer = nil;
        }
        
        self.isAutoCon = FALSE;
        
        UIViewController *target = nil;
        for (UIViewController * controller in self.navigationController.viewControllers) {
            //遍历
            if ([controller isKindOfClass:[DeviceViewController class]]) {
                //这里判断是否为你想要跳转的页面
                target = controller;
            }
        }
        if (target) {
            [self.navigationController popToViewController:target animated:YES]; //跳转
        }
    }else{
        NSLog(@"DDD-HHH-LLL%@",self.deviceTimer);
        NSLog(@"DDD-HHH-LLL%d",self.times);
    }
}

五:相关蓝牙列表的服务调用

-(BlueTempModel*)getBleTempModel{
    if(self.bleModel==nil){
        self.bleModel = [[BlueTempModel alloc] init];
    }
    return self.bleModel;
}
-(CommonDefaults*)getCmDefaults{
    if(self.cmDefaults==nil){
        self.cmDefaults = [[CommonDefaults alloc] init];
    }
    return self.cmDefaults;
}

-(BlueTempView *)getBlueTempView{
    if(self.btView==nil){
        self.btView = [[BlueTempView alloc] init];
    }
    return self.btView;
}

-(BlueTempModel *)getBlueTempModel{
    if(self.blueTempModel==nil){
        self.blueTempModel = [[BlueTempModel alloc] init];
    }
    return self.blueTempModel;
}

-(NSMutableArray *)gettempList{
    if(self.tempList==nil){
        self.tempList = [NSMutableArray array];
    }
    return self.tempList;
}

-(NSMutableArray*)getDeviceList{
    if(self.deviceList==nil){
        self.deviceList=[NSMutableArray array];
    }
    return self.deviceList;
}

-(NSMutableArray*)getPeripheralList{
    if(self.peripheralList==nil){
        self.peripheralList = [NSMutableArray array];
    }
    return self.peripheralList;
}

这篇博文总结了蓝牙自动链接的相关知识,判断到当设备断开之后,一定时间范围内,如果设备再次开启,App移动应用端将依旧链接,继续读取/写入相关数据,如果超出时间范围内,则进行返回退出链接界面,需要用times断开的次数,进行逻辑处理和功能需求的最终目的。

如果对您有所帮助,或者不懂之处可以留言,若有写的不对之处,欢迎志同道合的朋友一起学习,一起进步,谢谢您的阅读,别忘了点赞呀!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值