iOS开发—蓝牙4.0(BLE)与外设连接及收发数据的流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Alexander_Wei/article/details/69664308

苹果在iOS 6系统之后开始支持BLE 4.0,iPhone4s,iPod 5,iPad 3等之后的机型开始内嵌BLE4.0硬件,因此在开发前请先确认你的开发环境符合上述要求,并且苹果在BLE4.0之后,对外部的连接设备已经不再需要MFI认证了,当然你的外设肯定得要有蓝牙4.0模块。


开发BLE4.0的App,你需要在你的项目里面导入框架:



在需要使用到蓝牙的文件里面导入头文件,并且在你的蓝牙类里面实现两个协议,CBCentralManagerDelegate ,CBPeripheralDelegate

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>

@interface BluetoothEquipment : NSObject<CBCentralManagerDelegate,CBPeripheralDelegate>

现在我们需要有两个实例对象CBCentralManager和CBPeripheral,第一个是蓝牙中心管理器,主要用来搜索外设,连接外设以及处理外设断开的情况;第二个主要用于在蓝牙中心管理器成功连接外设之后的一系列动作,如:读取外设的服务号CBService,特征值号CBCharacteristic以及对这些特征值号进行读写操作等,下面我们来看一下中心管理器和外设连接的一个大概流程:

1):蓝牙中心管理器开始扫描广播包(扫描的时长可以自己写一个定时器控制,并且可以设定扫描的具体条件)

2):外设开始广播(当然外设的广播时长也是可以设定的)

3):中心管理器发现有广播包,就请求连接外设

4):连接成功之后就可以读取外设的相关信息了,比如服务号CBService,特征值号CBCharacteristic,还有外设的一些硬件信息,电池电量,信号强度RSSI什么的

5):当然在正常连接的过程中总会出现点意外,如果两个设备突然断掉了连接,一般我们还是希望它们能够再次连接的,这里就得要看硬件和程序里对于连接断开的处理代码了


编程代码:

创建BluetoothEquipment类,然后在BluetoothEquipment.h里

 
 

#define PERIPHERAL_NAME      @"KL940704079"

#import <Foundation/Foundation.h>

#import <CoreBluetooth/CoreBluetooth.h>

@interface BluetoothEquipment : NSObject<CBCentralManagerDelegate,CBPeripheralDelegate>

@property(nonatomic,strong)CBCentralManager* centralManager;

@property(nonatomic,strong)CBPeripheral* myPeripheral;

@property(nonatomic,strong)CBCharacteristic* lockUnlockCharacteristic;//上锁和解锁的characteristic

@property(nonatomic,strong)CBCharacteristic* readPowerCharacteristic;//电量的characteristic

-(void)initCentralManager;//初始化中心设备管理器

-(void)setLockInstruction:(NSString*)lockInstruction;//传入上锁指令

-(void)setUnlockInstruction:(NSString *)unlockInstruction;//传入解锁指令

@end


BluetoothEquipment.m里

 
 

#import "BluetoothEquipment.h"

@implementation BluetoothEquipment

//传入上锁指令

- (void)setLockInstruction:(NSString *)lockInstruction{

    if (_lockUnlockCharacteristic) {

        NSData* lockValue = [self dataWithString:lockInstruction];

        NSLog(@"上锁的指令lockValue= %@",lockValue);

        [_myPeripheral writeValue:lockValue forCharacteristic:_lockUnlockCharacteristic type:CBCharacteristicWriteWithResponse];

        }

}

//传入解锁指令

-(void)setUnlockInstruction:(NSString *)unlockInstruction{

    if (_lockUnlockCharacteristic) {

        NSData* unlockValue = [self dataWithString:unlockInstruction];

        NSLog(@"解锁的指令unlockValue= %@",unlockValue);

        

        [_myPeripheral writeValue:unlockValue forCharacteristic:_lockUnlockCharacteristic type:CBCharacteristicWriteWithResponse];

    }

}

//初始化中心设备管理器

- (void)initCentralManager{

    _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

}

//创建完成CBCentralManager对象之后会回调的代理方法

- (void)centralManagerDidUpdateState:(CBCentralManager *)central;

{

    if (central.state == CBCentralManagerStatePoweredOff) {

        NSLog(@"系统蓝牙关闭了,请先打开蓝牙");

    }if (central.state == CBCentralManagerStateUnauthorized) {

        NSLog(@"系统蓝未被授权");

    }if (central.state == CBCentralManagerStateUnknown) {

        NSLog(@"系统蓝牙当前状态不明确");

    }if (central.state == CBCentralManagerStateUnsupported) {

        NSLog(@"系统蓝牙设备不支持");

    }if (central.state == CBCentralManagerStatePoweredOn) {

        //扫描外设

         [_centralManager scanForPeripheralsWithServices:nil options:nil];//如果你将第一个参数设置为nil,Central Manager就会开始寻找所有的服务。

    }

}

//执行扫描的动作之后,如果扫描到外设了,就会自动回调下面的协议方法了

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI;{

//根据名字有选择性地连接蓝牙设备

    if([peripheral.name  isEqualToString:PERIPHERAL_NAME]){

        _myPeripheral = peripheral;

        _myPeripheral.delegate = self;

        //连接外设

        [_centralManager connectPeripheral:_myPeripheral options:nil];

    }

}

//如果连接成功,就会回调下面的协议方法了

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

    //停止中心管理设备的扫描动作,要不然在你和已经连接好的外设进行数据沟通时,如果又有一个外设进行广播且符合你的连接条件,那么你的iOS设备也会去连接这个设备(因为iOS BLE4.0是支持一对多连接的),导致数据的混乱。

    [_centralManager stopScan];

    

    

    //一次性读出外设的所有服务

    [_myPeripheral discoverServices:nil];

}

//掉线

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

    NSLog(@"掉线");

}

//连接外设失败

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error;

{

    NSLog(@"连接外设失败");

}

//一旦我们读取到外设的相关服务UUID就会回调下面的方法

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error;

{

    //到这里,说明你上面调用的  [_peripheral discoverServices:nil]; 方法起效果了,我们接着来找找特征值UUID

    NSLog(@"发现服务");

    for (CBService *s in [peripheral services]) {

       

        [peripheral discoverCharacteristics:nil forService:s];

    }

    

}

//如果我们成功读取某个特征值UUID,就会回调下面的方法

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

    for(int i=0; i < service.characteristics.count; i++) {

        

        CBCharacteristic *c = [service.characteristics objectAtIndex:i];

         NSLog(@"特征 UUID: %@ (%@)", c.UUID.data, c.UUID);

        

        if ([[c UUID] isEqual:[CBUUID UUIDWithString:@"0000fff6-0000-1000-8000-00805f9b34fb"]]){

            

            _lockUnlockCharacteristic = c;

            NSLog(@"找到可写特征lockUnlockCharacteristic : %@", c);

    }

        

        //读取蓝牙4.0设备电量的特征值

        if ([[c UUID] isEqual:[CBUUID UUIDWithString:@"0000fff4-0000-1000-8000-00805f9b34fb"]]){

            

            self.readPowerCharacteristic = c;

            NSLog(@"找到可读特征readPowerCharacteristic : %@", c);

            [self.myPeripheral setNotifyValue:YES forCharacteristic:_readPowerCharacteristic];

            }

    }

    

}

//向peripheral中写入数据后的回调函数

- (void)peripheral:(CBPeripheral*)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{

    NSLog(@"write value success(写入成功) : %@", characteristic);

}

//获取外设发来的数据,不论是read和notify,获取数据都从这个方法中读取

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

    [peripheral readRSSI];

    NSNumber* rssi = [peripheral RSSI];

    //读取BLE4.0设备的电量

    if([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"0000fff4-0000-1000-8000-00805f9b34fb"]]){

        NSData* data = characteristic.value;

        NSString* value = [self hexadecimalString:data];

        NSLog(@"characteristic(读取到的) : %@, data : %@, value : %@", characteristic, data, value);

        }

    

}

//将传入的NSData类型转换成NSString并返回

- (NSString*)hexadecimalString:(NSData *)data{

    NSString* result;

    const unsigned char* dataBuffer = (const unsigned char*)[data bytes];

    if(!dataBuffer){

        return nil;

    }

    NSUInteger dataLength = [data length];

    NSMutableString* hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];

    for(int i = 0; i < dataLength; i++){

        [hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];

    }

    result = [NSString stringWithString:hexString];

    return result;

}

//将传入的NSString类型转换成ASCII码并返回

- (NSData*)dataWithString:(NSString *)string{

    unsigned char *bytes = (unsigned char *)[string UTF8String];

    NSInteger len = string.length;

    return [NSData dataWithBytes:bytes length:len];

}

@end


猜你喜欢

转载自blog.csdn.net/Alexander_Wei/article/details/69664308