博客> IOS Bluetooth 4.0 完整使用
IOS Bluetooth 4.0 完整使用
2017-10-18 20:51 评论:0 阅读:267 嗲吗够
ios 蓝牙数据 十六进制

1、首先先对蓝牙状态的一种识别,使用ENUM进行状态判别,分别使用BluetoothState表示蓝牙连接状态和BluetoothFailState表示蓝牙连接失败的状态,对BluetoothState和BluetoothFailState设置成全局变量,如下方所示 typedef NS_ENUM(NSInteger, BluetoothState){
BluetoothStateDisconnect = 0,
BluetoothStateScanSuccess,
BluetoothStateScaning,
BluetoothStateConnected,
BluetoothStateConnecting
};

typedef NS_ENUM(NSInteger, BluetoothFailState){
BluetoothFailStateUnExit = 0,
BluetoothFailStateUnKnow,
BluetoothFailStateByHW,
BluetoothFailStateByOff,
BluetoothFailStateUnauthorized,
BluetoothFailStateByTimeout
};

2、在连接界面,如IsConnectBleViewController,在.h文件中定义 @property (strong, nonatomic) CBCentralManager centralManager;
@property (strong, nonatomic) CBPeripheral
discoveredPeripheral;
@property (strong, nonatomic) CBCharacteristic * writeCharachter;

在IsConnectBleViewController.m文件中 //蓝牙状态 -- self.seachRssultLabel为文本提示

  • (void)bleState
    {
    if (bluetoothFailState == BluetoothFailStateUnExit) {
    switch (bluetoothState) {
    case BluetoothStateConnected:
    self.searchResultLabel.text =[NSString stringWithFormat:@"%@",NSLocalizedString(@"已连接", nil)];

            break;  
        case BluetoothStateConnecting:  
            self.searchResultLabel.text = NSLocalizedString(@"连接中......", nil);  
    
            break;  
        case BluetoothStateDisconnect:  
            self.searchResultLabel.text = NSLocalizedString(@"蓝牙已断开", nil);  
    
            break;  
        case BluetoothStateScanSuccess:  
            self.searchResultLabel.text = NSLocalizedString(@"搜索成功,请选择你需要连接的蓝牙设备", nil);  
            break;  
        case BluetoothStateScaning:  
            self.searchResultLabel.text = NSLocalizedString(@"搜索中", nil);  
            break;  
        default:  
            break;  
    }  

    }else {
    switch (bluetoothFailState) {
    case BluetoothFailStateByHW:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙硬件不支持", nil);
    break;
    case BluetoothFailStateByOff:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙关闭了", nil);
    break;
    case BluetoothFailStateByTimeout:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接超时", nil);
    break;
    case BluetoothFailStateUnauthorized:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接失败", nil);
    break;
    case BluetoothFailStateUnKnow:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接错误", nil);
    break;
    case BluetoothFailStateUnExit:
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接中...", nil);
    break;
    default:
    break;
    }
    }

}

-------- 搜索蓝牙的办法 ----- [self.centralManager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey : @NO}];//搜索所有的蓝牙服务
self.centralManager.delegate = self;//必须遵循代理
bluetoothState = BluetoothStateScaning;//蓝牙状态变为搜索状态
[self bleState];
[self performSelector:@selector(searchBluetoothJumpTimeOut) withObject:nil afterDelay:10];//10表示搜索时间,10秒没有搜索到即定义为连接超时

pragma mark - 蓝牙连接超时的方法

  • (void)searchBluetoothJumpTimeOut
    {

    if (bluetoothState == BluetoothStateScaning) {
    bluetoothFailState = BluetoothFailStateByTimeout;
    [self ScanBle];//超时之后 -- 的操作,如果不需要超时后继续连接,则不需要这部步
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙连接超时,请重新搜索", nil);

    }
    }

pragma mark - 搜索蓝牙

-(void)ScanBle{

if(bluetoothFailState == BluetoothFailStateByTimeout){//连接超时  
    [self.centralManager scanForPeripheralsWithServices:nil  
                                                options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @NO }];  
    self.searchResultLabel.text = NSLocalizedString(@"正在搜索您的设备,请稍等...", nil);  

    bluetoothState = BluetoothStateScaning;//蓝牙状态变化成可搜索状态  

    [self bleState];//蓝牙的状态  

    [self performSelector:@selector(searchBluetoothJumpTimeOut) withObject:nil afterDelay:10];//如果连接超时  

}  

if(bluetoothFailState==BluetoothFailStateByOff){  
    self.promptLab.text= NSLocalizedString(@"检查您的蓝牙是否开启后重试", nil);//如果蓝牙设备关闭,提示打开蓝牙设备 -- 弹出视图提示  
    [self showPromptLab];  
}  

}

pragma mark CBCentralManagerDelegate --- 中心设备(手机)的代理方法,即上面定义的 self.centralManager.delegate = self;//必须遵循代理

监控手机的蓝牙状态,一旦蓝牙被关闭可提醒

  • (void)centralManagerDidUpdateState:(CBCentralManager *)central
    {
    if (central.state != CBCentralManagerStatePoweredOn) {//end to do
    // In a real app, you'd deal with all the states correctly

    NSLog(@"fail, state is off.");  
    
    switch (central.state) {  
        case CBCentralManagerStatePoweredOff:  
    
            self.searchResultLabel.text = NSLocalizedString(@"连接失败了,请您再检查一下您的手机蓝牙是否开启,然后再试一次吧", nil);  
            bluetoothFailState = BluetoothFailStateByOff;  
            break;  
    
        case CBCentralManagerStateResetting:  
            bluetoothFailState=BluetoothFailStateByTimeout;  
            break;  
    
        case CBCentralManagerStateUnsupported:  
            self.searchResultLabel.text = NSLocalizedString(@"检测到您的手机不支持蓝牙4.0,所以建立不了连接.建议更换您的手机再试试。", nil);  
            bluetoothFailState = BluetoothFailStateByHW;  
            break;  
    
        case CBCentralManagerStateUnauthorized:  
            self.searchResultLabel.text = NSLocalizedString(@"连接失败了,请您再检查一下您的手机蓝牙是否开启,然后再试一次吧", nil);  
            bluetoothFailState = BluetoothFailStateUnauthorized;  
            break;  
    
        case CBCentralManagerStateUnknown:  
            bluetoothFailState = BluetoothFailStateUnKnow;  
            self.searchResultLabel.text = @"";  
            break;  
    
        default:  
            break;  
    }  
    
    return;  

    }

    self.searchResultLabel.text = NSLocalizedString(@"蓝牙已经开启!点击开始搜索连接你的设备", nil);
    bluetoothFailState = BluetoothFailStateUnExit;

}

/ 中心设备扫描外围设备 / -(void)centralManager:(CBCentralManager )central didDiscoverPeripheral:(CBPeripheral )peripheral advertisementData:(NSDictionary )advertisementData RSSI:(NSNumber )RSSI{

if (peripheral == nil||peripheral.identifier == nil/*||peripheral.name == nil*/) {  
    return;  
}  

/* 
        蓝牙列表去重,防止重复的出现 --- 将 外围设备添加到数组中,主要针对多选,一对一可设置self.isConnectMuArra变成一个全局的peripheral 
 */  
NSMutableArray * repetitionMuArray = [[NSMutableArray alloc]init];  

[repetitionMuArray addObject:peripheral];  

for (unsigned i = 0; i < repetitionMuArray.count; i++) {  

    if ([self.isConnectMuArray containsObject:[repetitionMuArray objectAtIndex:i]] == NO) {  
        [self.isConnectMuArray addObject:[repetitionMuArray objectAtIndex:i]];  
    }  
}  

//搜索成功后,修改蓝牙状态  
bluetoothFailState = BluetoothFailStateUnExit;  
bluetoothState = BluetoothStateScanSuccess;//蓝牙状态为搜索成功  

[self bleState];//中心设备状态实时监控  

//输出广播名  
NSString *CBName1=[advertisementData valueForKeyPath:CBAdvertisementDataLocalNameKey];  
NSLog(@"广播名1:%@",CBName1);  

}

3、扫描设备成功后进行连接 for (int i = 0; i < self.isConnectMuArray.count ; i++) {
CBPeripheral * selectPeripheral = self.isConnectMuArray[i];
[self.centralManager connectPeripheral:selectPeripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@YES}];
}

连接之后执行连接的代理方法

pragma mark - 已经连接蓝牙设备

-(void)centralManager:(CBCentralManager )central didConnectPeripheral:(CBPeripheral )peripheral{

[self.centralManager stopScan];//连接成功后停止搜索  

bluetoothState=BluetoothStateConnected;  
[self bleState];  
//discoveredPeripheral是全部变量 多连接是否需要创建数组?  
discoveredPeripheral=peripheral;  /----   前面所说如果是需要一对一创建全局变量 -----  如果一对多,则选择下面一步添加数组/  
discoveredPeripheral.delegate = self;  
[(sysDege).discoverPeripheralArray addObject:peripheral];//(sysDege).discoverPeripheralArray是全局数组      

 [peripheral discoverServices:@[[CBUUID UUIDWithString:UUID_SERVICE]]];//设置扫描 -- 外围设备扫描自己的服务   UUID_SERVICE是硬件方面的序列号,可为nil  

[[NSNotificationCenter defaultCenter]postNotificationName:@"ConnectSuccess" object:nil];//通知成功的消息  

}

上一步连接成功外围设备,就开始发送扫描服务的指令,在这里执行扫描到服务的代理办法

pragma mark - 外围设备已经被发现

-(void)peripheral:(CBPeripheral )peripheral didDiscoverServices:(NSError )error{
if (error) {//如果发现错误
NSLog(@"Error discovering services: %@", [error localizedDescription]);
return;
}

NSLog(@"外围设备已被发现peripheral.services%@",peripheral.services);  

for (CBService * service in peripheral.services) {  

    [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:UUID_CHARACTERISTIC]] forService:service];//扫描到服务就可以发送扫描特性的指令  

    return;  
}  

}

pragma mark - 外围设备扫描到特性

-(void)peripheral:(CBPeripheral )aPeripheral didDiscoverCharacteristicsForService:(CBService )service error:(NSError *)error{

for (CBCharacteristic * achar in service.characteristics) {  

    NSLog(@"外围设备Discovered characteristic:CBCharacteristic * achar%@", achar);  

    NSLog(@"service uuid:%@ characteristics UUID:%@,achar.value:%@",service.UUID,achar.UUID,achar.value);  

pragma mark - 扫描到特性后 设置读写

    [aPeripheral readValueForCharacteristic:achar];  
    [aPeripheral setNotifyValue:YES forCharacteristic:achar];//修改通知的状态  

    //可读写的特性?  
    if (self.writeCharachter != achar) {  
        self.writeCharachter = achar;  
        writeCharachter = achar;  

    if (self.discoveredPeripheral != aPeripheral) {  
        self.discoveredPeripheral = aPeripheral;  
    }  
//可以通过不同的UUID进行发送不同的指令  
[self writeCommand:data];  
}  

}

pragma mark - 写入特性

-(void)writeCommand:(NSData *)data{

NSLog(@"writeCommand:(NSData *)data:%@",data);  
//    连接外围设备为空或者蓝牙状态为断开,退出  
if (self.discoveredPeripheral == nil||bluetoothState == BluetoothStateDisconnect) {  
    return;  
}  

[self.discoveredPeripheral writeValue:data  
                    forCharacteristic:self.writeCharachter  
                                 type:CBCharacteristicWriteWithResponse];  
NSLog(@"write command is success");  

}

//发送指令后可以得到硬件返回的信息

pragma mark - 特性值变化

  • (void) peripheral:(CBPeripheral )aPeripheral
    didUpdateValueForCharacteristic:(CBCharacteristic
    )characteristic
    error:(NSError *)error
    {

    NSLog(@"特性回调值:%@",characteristic);

    NSString *result = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
    NSLog(@"特性回调值的温度:%@",result);

}

连接不成功 -- 即断开

  • (void)centralManager:(CBCentralManager )central didDisconnectPeripheral:(CBPeripheral )peripheral error:(NSError *)error
    {

    self.discoveredPeripheral = nil;//断开之后为空 -- 一对一的方法,一对多为(sysDege).discoverPeripheralArray数组清空
    bluetoothState = BluetoothStateDisconnect;
    [self bleState];
    self.searchResultLabel.text = NSLocalizedString(@"蓝牙设备已经断开了,请重新搜索", nil);

    [[NSNotificationCenter defaultCenter]postNotificationName:@"bleDis" object:nil];//发送蓝牙断开的通知

}

蓝牙发送数据 -- self.discoveredPeripheral表示外围设备 --self.writeCharachter表示特性 [self.discoveredPeripheral writeValue:data
forCharacteristic:self.writeCharachter
type:CBCharacteristicWriteWithResponse];

收藏
0
sina weixin mail 回到顶部