iOS 蓝牙开发(一)

作者: Alexander | 来源:发表于2021-10-11 14:38 被阅读0次

前期回顾

iOS 蓝牙开发(二)
iOS 蓝牙开发(三)
iOS 蓝牙开发(四)

一、基本概念

  • 1.1,中心设备(central):是发起连接的主设备,如:App。
  • 1.2,外设(peripheral):被连接的设备称为外部设备,即外设, 如:体脂称,健康手环等;
  • 1.3,服务(CBService): 外设可以包含一个或多个服务,它是用于实现装置的功能或特征数据相关联的行为集合。
  • 1.4,特征(CBCharacteristic):每个服务可以对应多个特征,它是提供外设服务进一步的细节。
开始前先记录运行后的扫描结果
扫描结果和lightBule的对比

二,蓝牙相关实现

在iOS中蓝牙相关实现都是在CoreBluetooth这个framework中的,所以我们创建一个单例类中需要先导入#import <CoreBluetooth/CoreBluetooth.h>,再后即可使用这个单例类进行管理我们蓝牙的扫描、连接、状态等实现。

  • 2.1, 初始化蓝牙CBCentralManager
        dispatch_queue_t centralQueue = dispatch_queue_create("com.acadsoc.wgazjbuletoothsdk",DISPATCH_QUEUE_SERIAL);
        NSDictionary *options = @{CBCentralManagerOptionShowPowerAlertKey : [NSNumber numberWithBool:YES], CBCentralManagerOptionRestoreIdentifierKey : @"com.hykj.wgazjbuletoothsdk"};
        self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:centralQueue options:options];
                                    
//        self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
        self.resultStr = @"";
        self.services = [[NSMutableArray alloc]init];
  • 2.2,扫描周边可连接蓝牙设备
    当我们在扫描周边外设之前需要判断蓝牙是否可用,在- (void)centralManagerDidUpdateState:(CBCentralManager *)central函数中进行获取设备蓝牙的更新。

判断手机蓝牙状态
CBManagerStateUnknown = 0, 未知
CBManagerStateResetting, 重置中
CBManagerStateUnsupported, 不支持
CBManagerStateUnauthorized, 未验证
CBManagerStatePoweredOff, 未启动
CBManagerStatePoweredOn, 可用

central.state为CBManagerStatePoweredOn即可开始扫描, 具体方法[self.centralManager scanForPeripheralsWithServices:nil options:nil]当调用scanForPeripheralsWithServices:options:函数时就会实时调用其代理方法- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    
    if (self.stateUpdateBlock) {
        self.stateUpdateBlock(central.state);
    }
    switch (central.state)
    {
        case CBManagerStatePoweredOn:

            NSLog(@"蓝牙已开启");
            // 根据SERVICE_UUID来扫描外设,如果不设置SERVICE_UUID,则扫描所有蓝牙设备
            // 第一个参数为CBUUID的数组,需要搜索特点服务的蓝牙设备,只要每搜索到一个符合条件的蓝牙设备都会调用didDiscoverPeripheral代理方法
            [self startScan];
            break;
        case CBManagerStatePoweredOff:
            
            NSLog(@"蓝牙已关闭, 请打开蓝牙");
            break;
        case CBManagerStateUnsupported:
            NSLog(@"设备不支持蓝牙");
            break;
        case CBManagerStateUnauthorized:
            NSLog(@"应用尚未被授权使用蓝牙");
            break;
        case CBManagerStateUnknown:
            NSLog(@"未知错误,请重新开启蓝牙");
            break;
        case CBManagerStateResetting:
            NSLog(@"蓝牙重置中");
            [self stopScan];
            break;
        default:
            NSLog(@"Central Manager did change state");
            break;
    }
}

// 开始扫描周围可用蓝牙
- (void)startScan {
    
    //不重复扫描已发现设备
    //CBCentralManagerScanOptionAllowDuplicatesKey设置为NO表示不重复扫瞄已发现设备,为YES就是允许。
    //CBCentralManagerOptionShowPowerAlertKey设置为YES就是在蓝牙未打开的时候显示弹框
    NSDictionary *option = @{CBCentralManagerScanOptionAllowDuplicatesKey : [NSNumber numberWithBool:NO],CBCentralManagerOptionShowPowerAlertKey:[NSNumber numberWithBool:YES]};
    // 第一个参数填nil代表扫描所有蓝牙设备,第二个参数options也可以写nil
    [self.centralManager scanForPeripheralsWithServices:nil options:option];
}

// 扫描外设的代理方法,在该函数中揭开筛选出周边的蓝牙外设
// 在蓝牙于后台被杀掉时,重连之后会首先调用此方法,可以获取蓝牙恢复时的各种状态
- (void)centralManager:(CBCentralManager *)central
 didDiscoverPeripheral:(CBPeripheral *)peripheral
     advertisementData:(NSDictionary *)advertisementData
                  RSSI:(NSNumber *)RSSI
{
    NSString *perName = [[NSUserDefaults standardUserDefaults] objectForKey:@"conPeripheral"];
    NSString *setOrDelNum = [[NSUserDefaults standardUserDefaults] objectForKey:@"setOrDel"];

    // 检索到设备
    if (self.discoverPeripheralBlcok) {
        if (self.prefixString.length > 0) {
            if ([peripheral.name hasPrefix:self.prefixString]) {
                self.discoverPeripheralBlcok(central,peripheral,advertisementData,RSSI);
            }
        } else {
            self.discoverPeripheralBlcok(central,peripheral,advertisementData,RSSI);
        }
        [self startScan];
    }
    if ([setOrDelNum isEqualToString:@"0"]) {
        //有自动重连的设备
        [[NSNotificationCenter defaultCenter]postNotificationName:PostAutoConnectionNotificaiton object:nil];
        if ([peripheral.name isEqualToString:perName]) {
            self.peripheral = peripheral;
            [self.centralManager connectPeripheral:peripheral options:nil];
        }
    }
}

peripheral是外设类advertisementData是广播的值,一般携带设备名,serviceUUID等信息。RSSI绝对值越大,表示信号越差,设备离的越远。如果想装换成百分比强度,(RSSI+100)/1001(这是一个约数,蓝牙信号值并不一定是-100 - 0的值)

3,连接

蓝牙的连接是当中心设备扫描到可用外设后, 利用函数[self.centralManager connectPeripheral:peripheral options:nil];进行链接, 当函数被调用后, 就会回调其对应的代理函数。

  • 3.1,链接成功后的回调
// 蓝牙设备连接成功
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    [self.centralManager stopScan];
    [self.peripheral setDelegate:self];
    [self.peripheral discoverServices:nil];
    
    //延时操作
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        if (self.connectSuccessBlock) {
            self.connectSuccessBlock(peripheral,nil,self.writeCharacteristic);
        } else {
            //返回连接成功
            if ([self.delegate respondsToSelector:@selector(automaticConnectionWithPerpheral:)]) {
                [self.delegate automaticConnectionWithPerpheral:peripheral];
            }
        }
    });
}
  • 3.2, 链接失败后的回调
// 连接失败
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    if (self.connectFailureBlock) {
        self.connectFailureBlock(peripheral,error);
    }
}

4, 其他函数和代理方法

  • 4.1,断开链接
// 断开蓝牙连接
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    [self disconectPeripheral];
    if (error)
        {
        NSLog(@">>> didDisconnectPeripheral for %@ with error: %@", peripheral.name, [error localizedDescription]);
        }
}

// 断开链接
- (void)disconectPeripheral {
    
    if (self.peripheral) {
        [self.centralManager cancelPeripheralConnection:self.peripheral];
    }
}
  • 4.2,停止扫描
// 停止扫描
- (void)stopScan
{
    [self.centralManager stopScan];
}

5,中心管理供给外界使用方法

// 单例
+ (ZJAWGBluetoothManager *)defaultManager;

/**
 当前蓝牙的状态
 
 @param state  状态
 */
- (void)returnBluetoothStateWithBlock:(BTStateUpdateBlock)state;

/**
 搜索蓝牙外设, 每次回调表示返回一个蓝牙外设信息
 
 @param name  模糊搜索设备名称, 即目标设备名称包含的字段
 @param discoverBlock  搜索到蓝牙外设后的回调
 */
- (void)scanPeripheralsWithName:(NSString *)name
               discoverPeripheral:(BTDiscoverPeripheralBlock)discoverBlock;

/**
 搜索蓝牙外设
 
 @param discoverBlock  搜索蓝牙外设
 */
- (void)scanPeripheralsWithDiscoverPeripheral:(BTDiscoverPeripheralBlock)discoverBlock;

/**
 连接某个蓝牙外设,并查询服务,特性,服务等描述
 
 @param peripheral  要连接的蓝牙外设
 @param complete  连接成功后的回调
 @param failure  连接失败后的回调
 */
- (void)connectPeripheral:(CBPeripheral *)peripheral
                 complete:(BTConnectSuccessBlock)complete
                  failure:(BTConnectFailureBlock)failure;

总结

本篇笔记主要是记录如何初始化蓝牙的CBCentralManager的中心管理类,并记录如何实现扫描周边外设、如何链接、获取蓝牙当前状态。

相关文章

  • 【Objective-c】_蓝牙开发

    ios蓝牙开发学习笔记(一)蓝牙概述 ios蓝牙开发学习笔记(二)central角色的实现 ios蓝牙开发学习笔记...

  • iOS蓝牙开发(四):BabyBluetooth蓝牙库介绍

    iOS蓝牙开发(四):BabyBluetooth蓝牙库介绍 iOS蓝牙开发(四):BabyBluetooth蓝牙库介绍

  • iOS蓝牙开发(一)蓝牙相关基础知识

    iOS蓝牙开发一 iOS蓝牙开发(一)蓝牙相关基础知识 蓝牙常见名称和缩写 MFI ======= make fo...

  • iOS开发蓝牙4.0初识

    iOS开发蓝牙4.0初识转载 2015-09-20 15:26:44标签:ios开发蓝牙ios开发蓝牙4.0ios...

  • iOS蓝牙开发

    这篇文章主要包括iOS蓝牙开发的简介以及如果进行蓝牙开发, 具体的蓝牙知识不再详细介绍了. iOS蓝牙开发的实现基...

  • iOS蓝牙开发学习笔记 - 系列

    详见我的csdn: iOS蓝牙开发学习笔记(一)蓝牙概述 iOS蓝牙开发学习笔记(二)central角色的实现 i...

  • iOS蓝牙开发

    iOS蓝牙开发

  • 打印机

    iOS开发之蓝牙/Socket链接小票打印机(一)iOS开发之蓝牙/Socket链接小票打印机(二) iOS so...

  • ios蓝牙参考

    参考文章:iOS中的蓝牙开发iOS-BLE蓝牙开发demo 官网 转载 CenteralManager学习笔记

  • iOS蓝牙的开发专题

    iOS蓝牙的开发专题 最近做一个iOS蓝牙设备的项目,需要用iOS连接外部蓝牙设备,就对iOS蓝牙相关技术做了一些...

网友评论

    本文标题:iOS 蓝牙开发(一)

    本文链接:https://www.haomeiwen.com/subject/wiploltx.html