iOS BLE开发

iOS BLE开发

Android BLE开发的原理是一样的.手机做中心设备,iOS开发BLE:

蓝牙权限

在info.polist中添加权限Privacy - Bluetooth Peripheral Usage Description

封装单例

@interface XBBleHelper ()<CBCentralManagerDelegate,CBPeripheralDelegate>
@property (nonatomic,copy) BTDiscoverCompletion discoverComplection;
@property (nonatomic,copy) BTDevConnectedCompletion devConnectedComplection;
@property (nonatomic,copy) BTDevDisConnectedCompletion devDisconnectedComplection;

//中心管理者
@property (nonatomic,strong) CBCentralManager *centralMgr;
//检测到的所有设备
@property (nonatomic,strong) NSMutableArray *allPeripherals;
//是否系统蓝牙打开
@property (nonatomic,assign) BOOL isLocalBleOpen;
//读数据的特征
@property (nonatomic,strong) CBCharacteristic *readCharacteristic;
//写数据的特征
@property (nonatomic,strong) CBCharacteristic *writeCharacteristic;

@end

@implementation XBBleHelper

//是否连接成功
static bool isConnected = false;

//单例
static XBBleHelper *bleHelper = nil;
+ (instancetype)shareBleHelper{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        bleHelper = [[XBBleHelper alloc]init];
    });
    return bleHelper;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.isLocalBleOpen = NO;
        self.centralMgr =[[CBCentralManager alloc]initWithDelegate:self queue:dispatch_get_main_queue() options:nil];
        self.peripheralArray = [NSMutableArray array];
    }
    return self;
}
//开始扫描
- (void)startSearch{
    if (!self.isLocalBleOpen) {
        return;
    }
    [self stopSearch];
    [self.centralMgr scanForPeripheralsWithServices:nil options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil]];
}
//开始扫描
-(void)startSearchBTDevice:(BTDiscoverCompletion)discoverCompletion connectedCompletion:(BTDevConnectedCompletion)devConnected disconnectedCompletion:(BTDevDisConnectedCompletion)devDisconnect
{
    if (!self.isLocalBleOpen) {
        return;
    }
    //每次开始扫描之前先停止上一次的扫描,并将回调函数清空
    [self stopSearch];

    self.discoverComplection = discoverCompletion;
    self.devConnectedComplection = devConnected;
    self.devDisconnectedComplection = devDisconnect;

    [self.centralMgr scanForPeripheralsWithServices:nil options:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],CBCentralManagerScanOptionAllowDuplicatesKey, nil]];
}

//停止扫描
- (void)stopSearch{
    [self.centralMgr stopScan];
    [self.peripheralArray removeAllObjects];

    self.discoverComplection = nil;
    self.devDisconnectedComplection = nil;
    self.devConnectedComplection = nil;
}
//是否连接成功
-(BOOL) isConnected
{
    return isConnected;
}
//是否本地蓝牙打开
- (BOOL)isLocalBleOpen{
    return _isLocalBleOpen;
}

//连接外设
- (void)connectPeripheralAtIndex:(NSUInteger)aIndex{
    if(self.peripheralArray.count < aIndex+1)
        return;
    CBPeripheral * peripheral = [self.peripheralArray objectAtIndex:aIndex];
    self.currentPeripheral = peripheral;
    if (peripheral.state == CBPeripheralStateConnected) {
        [self.centralMgr cancelPeripheralConnection:peripheral];
    }else{
        [self.centralMgr connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
         [[NSNotificationCenter defaultCenter] postNotificationName:KNOTIFICATION_START_BTCONNECT object:nil];//蓝牙开始连接
    }
}
//断开蓝牙外设
- (void)disconnectCurrentBTDevice{
    if (self.currentPeripheral.state == CBPeripheralStateConnected ) {
        [self.centralMgr cancelPeripheralConnection:self.currentPeripheral];
    }
}
//设置通知
- (void)setCharacteristic:(CBCharacteristic *)characteristic toNotifyValue:(BOOL)enabled {
    [self.currentPeripheral setNotifyValue:enabled forCharacteristic:characteristic];
}
- (void)sendData:(NSData *)data{
    [self.currentPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
}
#pragma mark --- CBCentralManagerDelegate
//centralMgr状态改变,只有设备打开后才会能扫描设备
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    switch (central.state) {
        case CBCentralManagerStateUnknown:
            HT_LLog(@">>>>>>>CBCentralManagerStateUnknown");
            //break;
        case CBCentralManagerStateResetting:
            HT_LLog(@">>>>>>>CBCentralManagerStateResetting");
            //break;
        case CBCentralManagerStateUnsupported:
            HT_LLog(@">>>>>>>CBCentralManagerStateUnsupported");
            //break;
        case CBCentralManagerStateUnauthorized:
            HT_LLog(@">>>>>>>CBCentralManagerStateUnauthorized");
            //break;
        case CBCentralManagerStatePoweredOff:
            HT_LLog(@">>>>>>>CBCentralManagerStatePoweredOff");
            self.isLocalBleOpen = NO;
            break;
        case CBCentralManagerStatePoweredOn:
            HT_LLog(@">>>>>>>CBCentralManagerStatePoweredOn");
            self.isLocalBleOpen = YES;
            //在此时开始扫描设备
            break;
        default:
            break;
    }

}
//当扫描到外设的时候,会进入到该方法
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI{

    if([self.peripheralArray containsObject:peripheral] || ![peripheral.name containsString:@"--"])
    {
        return;
    }
    [self.peripheralArray addObject:peripheral];
    if (self.discoverComplection){
        self.discoverComplection();//扫描到外设
    }
}

//外设连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    if (self.devConnectedComplection){
        self.devConnectedComplection();
    }
    self.currentPeripheral = peripheral;
    if (self.delegate) {
        [self.delegate bleDidConnect];
    }
    isConnected = true;
    peripheral.delegate = self;
    [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]];

}

//外设连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    self.currentPeripheral = nil;
    isConnected = false;

}

//外设断开连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    self.currentPeripheral = nil;
    isConnected = false;
    if (self.devDisconnectedComplection) {
        self.devDisconnectedComplection();
    }
    if (self.delegate) {
        [self.delegate bleDidDisconnect];
    }
}
#pragma mark --- CBPeripheralDelegate

//扫描外设的所有服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error{
    if (error){
        HT_LLog(@"error:%@",[error localizedDescription]);
        return;
    }

    for (CBService *service in peripheral.services) {
        if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
}

//
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverIncludedServicesForService:(CBService *)service error:(nullable NSError *)error{

}

//扫描特定服务的所有特征
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error{
    if (error)
    {
        HT_LLog(@"error Discovered characteristics for %@ with error: %@", service.UUID, [error localizedDescription]);
        return;
    }

    //搜索第一个服务
    if([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]){
        for (CBCharacteristic *characteristic  in service.characteristics) {
            HT_LLog(@"service:%@ characteristic:%@",service.UUID,characteristic);
            if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristerUUID]]) {
                if (characteristic.properties & 2) {
                    self.readCharacteristic = characteristic;
                    //通知的方式,读取这个特征的value
                    [self setCharacteristic:characteristic toNotifyValue:YES];
                }
                if (characteristic.properties & 4) {
                    self.writeCharacteristic = characteristic;
                }
            }
        }
    }
}
//读取特征的值,或者通知的方式读取特征的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{
    //接收到数据
    if(self.delegate){
      [self.delegate bleDidReceivedData:characteristic.value];
    }
}

//向特征写入值后的反馈
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{


}

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

}

//扫描特定特征的描述
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(nullable NSError *)error{

}

//读取描述的值
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error{

}

//向描述中写入值后的反馈
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForDescriptor:(CBDescriptor *)descriptor error:(nullable NSError *)error{

}


- (void)peripheralDidUpdateName:(CBPeripheral *)peripheral NS_AVAILABLE(NA, 6_0){

}

- (void)peripheral:(CBPeripheral *)peripheral didModifyServices:(NSArray<CBService *> *)invalidatedServices NS_AVAILABLE(NA, 7_0){

}

- (void)peripheralDidUpdateRSSI:(CBPeripheral *)peripheral error:(nullable NSError *)error NS_DEPRECATED(NA, NA, 5_0, 8_0){

}
- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(nullable NSError *)error NS_AVAILABLE(NA, 8_0){

}
@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值