转载

iOS低功耗蓝牙4.0开发

//

//  BlueTooth.h

//  BleDemo

//

//  Created by 张高强 on 2017/11/7.

//  Copyright © 2017年 liuyanwei. All rights reserved.

//

#import

#import

/**

 枚举定义蓝牙所有指令状态

 */

typedef NS_ENUM(NSUInteger,CommandState){

    CommandStateOpen = 0,//打开蓝牙

    CommandStateClose,  //关闭蓝牙

    CommandStateQuery   //查询蓝牙状态

};


typedef NS_ENUM(NSUInteger,PhoneBluetoothState){

    PhoneBluetoothStateOpen=0,//手机蓝牙状态打开

    PhoneBluetoothStateClose //手机蓝牙关闭

    

};

@protocol BlueToothDelegate<NSObject>

@optional

//点击开始连接蓝牙按钮

-(void)didClickStart;

//连接成功

- (void)BLEConnectSucceed;

//收到的数据

- (void)receivedValue:(NSString *)data;

//打开蓝牙提示

-(void)openBluetooth;

//连接蓝牙失败

-(void)connectFail;


@end

@interface BlueTooth : NSObject<CBPeripheralDelegate,CBCentralManagerDelegate>{

    NSInteger index;

}

//代理

@property (nonatomic, weak) id<BlueToothDelegate> delegate;

//中心

@property (nonatomic,strong) CBCentralManager *centralManager;

//外设

@property (nonatomic,strong) CBPeripheral *peripheral;

@property(nonatomic,strong)CBCharacteristic *notifyCharteristic;

//特征

@property (nonatomic, strong) CBCharacteristic *characteristic;

@property(nonatomic,strong)CBCentralManager *central;//中心设备管理

@property(nonatomic,copy)NSString *peripheralName;//传入的需要连接的外设

@property(nonatomic,assign)CommandState command;//外设具体指令状态

@property(nonatomic,assign)PhoneBluetoothState phoneState;

@property(nonatomic,assign)BOOL connectFlag;//判断是否连接中

//初始化

+ (instancetype)sharedInstance;

//开始连接

- (void)startConnect;

//断开连接

- (void)endConnect;


-(void)open;

-(void)close;

-(void)query;

以上是.h问价中定义的方法和回调方法

下面是.m文件中的方法


//

//  BlueTooth.m

//  BleDemo

//

//  Created by 张高强 on 2017/11/7.

//  Copyright © 2017年 liuyanwei. All rights reserved.

//


#import "BlueTooth.h"

@implementation BlueTooth


#define kServiceUUID        @"0003CDD0-0000-1000-8000-00805F9B0131" //服务的UUID

#define kWriteCharacteristicUUID @"0003CDD2-0000-1000-8000-00805F9B0131" //特征的UUID

#define kNotifyCharacteristicUUID @"0003CDD1-0000-1000-8000-00805F9B0131" //特征的UUID

 static id _instance;

/**

 创建单例对象

 @return 返回唯一实例

 */

+(instancetype)sharedInstance{

    @synchronized(self){

        if(_instance == nil){

            _instance = [[self alloc] init];

        }

    }

    return _instance;

}

/**

 开始连接蓝牙

 */

-(void)startConnect{

    if (self.delegate && [self.delegate respondsToSelector:@selector(didClickStart)])

    {

        //控制器更新UI

        [self.delegate didClickStart];

    }

    self.connectFlag =NO;

    //初始化中心端,开始蓝牙模块

    self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];

    self.centralManager.delegate = self;

}


//断开连接

- (void)endConnect

{

    self.connectFlag=NO;

    [self.centralManager cancelPeripheralConnection:self.peripheral];

       _centralManager=nil;

}

#pragma mark - CBCentralManagerDelegate



-(void)connectDeviceFailer{

    if ([self.delegate respondsToSelector:@selector(connectFail)]) {

        [self.delegate connectFail];

    }

    

}

// 状态更新后触发

-(void)centralManagerDidUpdateState:(CBCentralManager *)central

{

    switch (central.state) {

        case CBManagerStatePoweredOff:{

            NSLog(@"蓝牙关闭");

             self.phoneState = PhoneBluetoothStateClose;

            //检测到蓝牙没打开需要通知代理控制器去执行相关提示操作

            if (self.delegate && [self.delegate respondsToSelector:@selector(openBluetooth)])

            {

                [self.delegate openBluetooth];

             

            };

           

        }

            break;

        case CBManagerStatePoweredOn:{

               [self performSelector:@selector(connectDeviceFailer) withObject:self afterDelay:2.0];

            self.phoneState = PhoneBluetoothStateOpen;

        

            //检测到蓝牙没打开需要通知代理控制器去执行相关提示操作

            if (self.delegate && [self.delegate respondsToSelector:@selector(openBluetooth)])

            {

                [self.delegate openBluetooth];

            };

        }

           

            break;

        case CBManagerStateResetting:

            break;

        case CBManagerStateUnauthorized:

            break;

        case CBManagerStateUnknown:

            break;

        case CBManagerStateUnsupported:

            break;

        default:

            break;

    }

    [central scanForPeripheralsWithServices:nil options:nil];

}


// 扫描到外部设备后触发的代理方法//多次调用的

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(nonnull CBPeripheral *)peripheral advertisementData:(nonnull NSDictionary<NSString *,id> *)advertisementData RSSI:(nonnull NSNumber *)RSSI

{

    NSString *msg = [NSString stringWithFormat:@"信号强度: %@, 外设: %@", RSSI, peripheral];

    NSLog(@"%@",msg);

    //ZIH0491300//

//    NSLog(@"此时外设名字是%@",_peripheralName);

//    NSAssert(![_peripheralName isEqualToString:@""]||_peripheralName==nil, @"please init correct peripheralName");断言

        if ([peripheral.name isEqualToString:_peripheralName])

        {

            //连接外部设备

            self.peripheral = peripheral;

            [central connectPeripheral:peripheral options:nil];

            //停止搜索

            self.central=central;

            [central stopScan];

            

        }else{

            

        }

}

//连接失败

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

{

    NSLog(@"连接失败%@",error.localizedDescription);

    if ([self.delegate respondsToSelector:@selector(connectFail)]) {

        [self.delegate connectFail];

    }

}


// 当中心端连接上外设时触发

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

{

    NSLog(@"连接上外设");

    self.connectFlag=YES;

    

    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    [central stopScan];

    if ([self.delegate respondsToSelector:@selector(BLEConnectSucceed)]) {

        [self.delegate BLEConnectSucceed];

    }

    self.peripheral.delegate = self;

    [peripheral discoverServices:nil];

}


//如果连接上的两个设备突然断开了,程序里面会自动回调下面的方法

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

{

        [self.central connectPeripheral:peripheral options:nil];

    

    NSLog(@"已经断开蓝牙连接");

}

#pragma mark - CBPeripheralDelegate

// 外设端发现了服务时触发

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

{

    if (error)

    {

        NSLog(@"%@",error.localizedDescription);

        return;

    }

    for (CBService *service in peripheral.services)

    {

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

              [peripheral discoverCharacteristics:nil forService:service];

        }

    }

}


//从服务获取特征

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

{

   NSLog(@"%@",service.characteristics);

    for (CBCharacteristic *characteristic in service.characteristics)

    {

        

        if ([characteristic.UUID.UUIDString isEqualToString:kWriteCharacteristicUUID]  ) {

             self.characteristic = characteristic;

        }

        if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]) {

            self.notifyCharteristic=characteristic;

        }

      

    }

}


#pragma mark 写数据后回调

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

    if (error) {

        NSLog(@"Error writing characteristic value: %@",

              [error localizedDescription]);

        return;

    }

    NSLog(@"写入%@成功",characteristic);

}



-(void)query{

    [self.peripheral setNotifyValue:YES forCharacteristic:self.notifyCharteristic];

}

/**

 打开蓝牙

 */

-(void)open{

    NSData *data = [@"&1&1&1&1" dataUsingEncoding:NSUTF8StringEncoding];

    [self.peripheral writeValue:data forCharacteristic:self.characteristic type:0x04];

     [self.peripheral setNotifyValue:YES forCharacteristic:self.notifyCharteristic];

}


/**

 关闭蓝牙

 */

-(void)close{

    NSData *data = [@"&&&2&" dataUsingEncoding:NSUTF8StringEncoding];

    [self.peripheral writeValue:data forCharacteristic:self.characteristic type:0x04];

     [self.peripheral setNotifyValue:YES forCharacteristic:self.notifyCharteristic];

}


//将十六进制的字符串转换成NSString则可使用如下方式:

+ (NSString *)convertHexStrToString:(NSString *)str {

    if (!str || [str length] == 0) {

        return nil;

    }

    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];

    NSRange range;

    if ([str length] % 2 == 0) {

        range = NSMakeRange(0, 2);

    } else {

        range = NSMakeRange(0, 1);

    }

    for (NSInteger i = range.location; i < [str length]; i += 2) {

        unsigned int anInt;

        NSString *hexCharStr = [str substringWithRange:range];

        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];

        [scanner scanHexInt:&anInt];

        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];

        [hexData appendData:entity];

        range.location += range.length;

        range.length = 2;

    }

    NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];

    return string;

}


//收到数据,并且通知代理接受数据,并实现相关功能

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

{

    NSString *results=[[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];

   

        if ([self.delegate respondsToSelector:@selector(receivedValue:)]) {

            [self.delegate receivedValue:results];

        }

}

如果有兴趣可以去https://github.com/zhanggaoqiang/GQBluetooth下载源文件阅读

正文到此结束
Loading...