iOS蓝牙开发封装

#import <Foundation/Foundation.h>

#import <CoreBluetooth/CoreBluetooth.h>

#import "BTAllBlock.h"

#import "BTString.h"

#define BtServiceUUID @"FFE0"  // 服务 UUID

#define BtCharacteristicUUID @"FFE1" // 特征透传通道UUID

@interface BTManager : NSObject <CBPeripheralDelegate,CBCentralManagerDelegate>

{

    /** 蓝牙状态*/

    BluetoothStateUpdateBlock  btStateUpdateBlock;

    /** 发现一个蓝牙外设的回调 */

扫描二维码关注公众号,回复: 2136148 查看本文章

    DiscoverPeripheralBlock    btDiscoverPeripheralBlcok;

    /** 连接外设完成的回调 */

    ConnectSuccessBlock        btConnectSuccessBlock;

    /** 连接外设失败的回调 */

    ConnectFailedBlock         btConnectFailBlock;

    /** 连接断开的回调 */

    DisConnectBlock            btDisConnectBlock;

    /** 将数据写入特性中的回调*/

    WriteToCharacteristicBlock btWriteToCharacteristicBlock;

    /** 设备响应数据回调*/

    EquipmentReturnBlock       btEquipmentReturnBlock;

}

+(instancetype)share;

/**系统当前蓝牙的状态

 * @param stateBlock 实时返回当前蓝牙状态

 */

- (void)returnBluetoothStateWithBlock:(BluetoothStateUpdateBlock)stateBlock;

/**开始搜索蓝牙外设,每次在block中返回一个蓝牙外设信息

 * @param macHexStr  模糊搜索设备amc,目标设备名称包含字段(该参数视需求而定)

 * 返回的block参数可参考CBCentralManager 的 centralManager:didDiscoverPeripheral:advertisementData:RSSI:

 * @param discoverBlock 搜索到蓝牙外设后的回调

 */

- (void)scanForPeripheralsWithMacHexString:(NSString *)macHexStr

                        discoverPeripheral:(DiscoverPeripheralBlock)discoverBlock;

/**连接某个蓝牙外设,并查询服务,特性,特性描述

 * @param completionBlock     操作执行完的回调

 */

- (void)connectPeripheralCompleteBlock:(ConnectSuccessBlock)completionBlock

                             failBlock:(ConnectFailedBlock)failBlock

                       disConnectBlick:(DisConnectBlock)disConnectBlick;

/**往某个特性中写入数据,自动识别数据长度超过限制分段传输

 * @param hexStr       写入的十六进制数据(0C22FF)

 * @param completionBlock 写入完成后的回调,只有type为CBCharacteristicWriteWithResponse时,才会回调

 */

- (void)writeValueHexString:(NSString *)hexStr completionBlock:(WriteToCharacteristicBlock)completionBlock returnBlock:(EquipmentReturnBlock)equipmentBlock;

/**

 * 停止扫描

 */

- (void)stopScan;

/**

 * 断开蓝牙连接

 */

- (void)cancelPeripheralConnection;

@end


#import "BTManager.h"


@implementation BTManager

{

    CBCentralManager *btCentralManager;

    // 模糊搜索参数

    NSString * btMaxHexStr;

    //

    CBPeripheral * btPeripheral;

    CBService    * btService;

    CBCharacteristic * btCharacteristic;

    // 写入数据是否回复

    BOOL btIsResponse;

    NSError * error;

    

}

static BTManager *shareManager = nil;

+(instancetype)share{

    static dispatch_once_t oneToken;

    dispatch_once(&oneToken, ^{

        shareManager = [[BTManager alloc]init];

    });

    return shareManager;

}

- (instancetype)init

{

    self = [super init];

    if (self) {

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

        btIsResponse = NO;

    }

    return self;

}

- (void)dealloc

{

    btCentralManager.delegate = nil;

    btPeripheral.delegate = nil;

}

#pragma mark -

//主设备状态改变

- (void)centralManagerDidUpdateState:(nonnull CBCentralManager *)central {

    if(btStateUpdateBlock){

        btStateUpdateBlock(central);

    }

}


//扫描到设备

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

    NSString * mac = @"";

    for(NSString * key in [advertisementData allKeys]){

        if([key isEqualToString:@"kCBAdvDataManufacturerData"]){

            NSString * hexString = [[BTString share] hexStringFromData:advertisementData[key]];

            //NSLog(@"hexString = %@",hexString);

            if(hexString.length == 20){

                mac = [hexString substringFromIndex:8];

            }

        }

    }

    NSString * sixString1 = [[BTString share] sixStrFromeHexString:mac];

    NSString * sixString2 = [[BTString share] sixStrFromeHexString:btMaxHexStr];

    if(btMaxHexStr.length>0&&[sixString1 isEqualToString:sixString2]){

        btPeripheral = peripheral;

        if(btDiscoverPeripheralBlcok){

            btDiscoverPeripheralBlcok(central,peripheral,advertisementData,RSSI);

        }

    }

}


//连接到Peripherals-成功

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

{   //设置的peripheral委托CBPeripheralDelegate

    [peripheral setDelegate:self];

    //扫描外设Services

    [peripheral discoverServices:nil];

}

//连接到Peripherals-失败

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

{

    if(btConnectFailBlock){

        btConnectFailBlock(peripheral,error);

    }

}

//Peripherals断开连接

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

    if(btDisConnectBlock){

        btDisConnectBlock(peripheral,error);

    }

    btPeripheral = nil;

    btCharacteristic = nil;

}

//扫描到Services 1

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

    if (error){

        if(btConnectFailBlock){

            btConnectFailBlock(peripheral,error);

        }

        return;

    }

    for (CBService *service in peripheral.services) {

        NSString * serverId = [[NSUserDefaults standardUserDefaults] objectForKey:@"BLEService"];

        serverId = [self UUIDWithString:serverId isServerId:YES];

        if([service.UUID.UUIDString isEqualToString:serverId]){

            btService = service;

            //扫描每个service的Characteristics

            [peripheral discoverCharacteristics:nil forService:service];

        }

        //NSLog(@"service == %@",service.UUID.UUIDString);

    }

}

//扫描到Characteristics

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

    if (error){

        if(btConnectFailBlock){

            btConnectFailBlock(peripheral,error);

        }

        return;

    }

    for (CBCharacteristic *characteristic in service.characteristics){

        NSString * characteristicId = [[NSUserDefaults standardUserDefaults] objectForKey:@"BLECharacteristic"];

        characteristicId = [self UUIDWithString:characteristicId isServerId:NO];

        if([characteristic.UUID.UUIDString isEqualToString:characteristicId]){ // 透传通道

            //[peripheral readValueForCharacteristic:characteristic];

            [peripheral setNotifyValue:YES forCharacteristic:characteristic];

            btCharacteristic = characteristic;

            if(btConnectSuccessBlock){

                btConnectSuccessBlock(peripheral,service,characteristic);

            }

        }

        //NSLog(@"characteristic == %@",characteristic.UUID.UUIDString);

    }

    //搜索Characteristic的Descriptors

//    for (CBCharacteristic *characteristic in service.characteristics){

//       // [peripheral discoverDescriptorsForCharacteristic:characteristic];

//    }

}

//获取的charateristic的值  //获取到特征的值时回调, 蓝牙回复

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

    if(btEquipmentReturnBlock && error==nil && characteristic.value != [NSData data] ){

        btEquipmentReturnBlock(peripheral,characteristic,characteristic.value,error);

        btIsResponse = YES;

    }

    //NSLog(@"value = %@ ,data = %@",characteristic.value,[NSData data]);

}


// 写入是否成功

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

    btWriteToCharacteristicBlock(characteristic,error);

}


//订阅的特征值有新的数据时回调

- (void)peripheral:(CBPeripheral *)peripheral

didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic

             error:(NSError *)error {

    if (error) {

        NSLog(@"Error changing notification state: %@",

              [error localizedDescription]);

    }

    [peripheral readValueForCharacteristic:characteristic];

}


#pragma mark -

/** 蓝牙的状态*/

- (void)returnBluetoothStateWithBlock:(BluetoothStateUpdateBlock)stateBlock{

    btStateUpdateBlock = stateBlock;

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

}

//搜索蓝牙外设

- (void)scanForPeripheralsWithMacHexString:(NSString *)macHexStr discoverPeripheral:(DiscoverPeripheralBlock)discoverBlock{

    btMaxHexStr  = macHexStr;

    btDiscoverPeripheralBlcok = discoverBlock;

    // 搜索

    [btCentralManager scanForPeripheralsWithServices:nil options:nil];

}

// 连接

- (void)connectPeripheralCompleteBlock:(ConnectSuccessBlock)completionBlock

                             failBlock:(ConnectFailedBlock)failBlock

                       disConnectBlick:(DisConnectBlock)disConnectBlick{

    btConnectSuccessBlock = completionBlock;

    btConnectFailBlock    = failBlock;

    btDisConnectBlock = disConnectBlick;

    if(btPeripheral){

        //连接设备

        [btCentralManager connectPeripheral:btPeripheral options:nil];

    }else{

        failBlock(nil,error);

    }

}

// 写数据

- (void)writeValueHexString:(NSString *)hexStr completionBlock:(WriteToCharacteristicBlock)completionBlock returnBlock:(EquipmentReturnBlock)equipmentBlock{

    btWriteToCharacteristicBlock = completionBlock;

    btEquipmentReturnBlock = equipmentBlock;

    NSData * data = [[BTString share] byteDataWithHexString:hexStr];

    if(btPeripheral && btCharacteristic){

        btIsResponse = NO;

        [btPeripheral writeValue:data forCharacteristic:btCharacteristic type:CBCharacteristicWriteWithResponse];//

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            sleep(1.5);

            dispatch_async(dispatch_get_main_queue(), ^{

                if(btIsResponse == NO){

                    equipmentBlock(btPeripheral,btCharacteristic,[NSData data],error);

                }

            });

        });

    }else{

        completionBlock(nil,error);

    }

}

// 停止扫描

- (void)stopScan{

    [btCentralManager stopScan];

}

//断开蓝牙连接

- (void)cancelPeripheralConnection

{

    if (btPeripheral) {

        [btCentralManager cancelPeripheralConnection:btPeripheral];

    }

}


// 处理UIUID

-(NSString *)UUIDWithString:(NSString *) string isServerId:(BOOL) isSer{

    //NSLog(@"UUID = %@",string);

    NSString * resString = isSer == YES ? BtServiceUUID:BtCharacteristicUUID;

    if(string.length>=8){

        NSRange range = NSMakeRange(4, 4);

        string = [string substringWithRange:range];//截取范围内的字符串

        // 小写

        NSString *lower = [string lowercaseString];

        // 大写

        NSString *upper = [lower uppercaseString];

        

        resString = upper;

    }

    return  resString;

}

二、block回调头文件BTAllBlock.h


#ifndef BTAllBlock_h

#define BTAllBlock_h


/** 蓝牙状态改变的block */

typedef void(^BluetoothStateUpdateBlock)(CBCentralManager *central);

/** 发现一个蓝牙外设的block */

typedef void(^DiscoverPeripheralBlock)(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI);

/** 连接完成的block*/

typedef void(^ConnectSuccessBlock)(CBPeripheral *peripheral,CBService *service, CBCharacteristic *character);

/** 连接失败的block*/

typedef void(^ConnectFailedBlock)(CBPeripheral *peripheral, NSError *error);

/** 断开连接的block*/

typedef void(^DisConnectBlock)(CBPeripheral *peripheral, NSError *error);

/** 往特性中写入数据的回调 */

typedef void(^WriteToCharacteristicBlock)(CBCharacteristic *characteristic, NSError *error);

/** 设备返回数据的回调 */

typedef void(^EquipmentReturnBlock)(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSData *returnData, NSError *error);


#endif /* BTAllBlock_h */




@end



猜你喜欢

转载自blog.csdn.net/qq_37191821/article/details/80835568