MST

星途 面试题库

面试题:Objective-C中Core Bluetooth蓝牙通信的连接流程

请详细描述在Objective-C中,使用Core Bluetooth框架进行蓝牙设备连接的主要步骤,包括中心角色和外设角色分别需要做哪些操作,以及相关的关键类和方法。
33.1万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

中心角色操作步骤

  1. 导入框架:在项目中导入Core Bluetooth框架。
  2. 初始化CBCentralManager
    • 创建CBCentralManager实例,通常在类的属性中定义。
    • 实现CBCentralManagerDelegate代理协议。
    • 使用initWithDelegate:queue:options:方法初始化CBCentralManager,其中delegate为当前类实例,queue可以传入nil使用主线程,options一般为nil
    • 关键代码示例:
@property (nonatomic, strong) CBCentralManager *centralManager;
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];
  1. 等待中心管理器状态更新:实现centralManagerDidUpdateState:代理方法,检查中心管理器的状态,只有当状态为.poweredOn时,才可以进行后续操作。
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if (central.state == CBCentralManagerStatePoweredOn) {
        // 可以开始扫描
        [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    }
}
  1. 扫描外设:调用scanForPeripheralsWithServices:options:方法扫描附近的蓝牙外设。services参数可以传入nil扫描所有设备,也可以传入特定的CBUUID数组来扫描特定服务的设备。options参数一般为nil
  2. 发现外设:实现centralManager:didDiscoverPeripheral:advertisementData:RSSI:代理方法,在此方法中获取发现的外设信息。可以存储外设对象,以便后续连接。
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"发现外设: %@", peripheral.name);
    self.discoveredPeripheral = peripheral;
    [self.centralManager stopScan];
    [self.centralManager connectPeripheral:peripheral options:nil];
}
  1. 连接外设:调用connectPeripheral:options:方法连接特定的外设,options参数一般为nil
  2. 处理连接结果:实现centralManager:didConnectPeripheral:centralManager:didFailToConnectPeripheral:error:代理方法,处理连接成功或失败的情况。
    • 连接成功后,可以发现外设的服务和特征。
    • 连接失败时,根据error信息处理错误。
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    NSLog(@"连接成功");
    [peripheral discoverServices:nil];
}
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
    NSLog(@"连接失败: %@", error);
}
  1. 发现服务和特征
    • 连接成功后,调用外设的discoverServices:方法发现外设提供的服务,services参数可以传入nil发现所有服务,也可以传入特定的CBUUID数组发现特定服务。
    • 实现peripheral:didDiscoverServices:代理方法,在方法中遍历发现的服务,并对每个服务调用discoverCharacteristics:forService:方法发现服务中的特征,characteristics参数同样可以传入nil或特定的CBUUID数组。
    • 实现peripheral:didDiscoverCharacteristicsForService:error:代理方法处理发现特征的结果。
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
        [peripheral discoverCharacteristics:nil forService:service];
    }
}
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
        NSLog(@"发现特征: %@", characteristic);
    }
}
  1. 数据交互:根据特征的属性(如可读、可写等)进行数据读写操作。
    • 读取数据:调用readValueForCharacteristic:方法读取特征的值,并实现peripheral:didUpdateValueForCharacteristic:error:代理方法获取读取到的数据。
    • 写入数据:调用writeValue:forCharacteristic:type:方法写入数据到特征,type参数根据特征的属性选择合适的写入类型。如果特征支持通知,还可以调用setNotifyValue:forCharacteristic:方法开启通知,实现peripheral:didUpdateNotificationStateForCharacteristic:error:peripheral:didUpdateValueForCharacteristic:error:代理方法处理通知相关操作。
  2. 断开连接:调用cancelPeripheralConnection:方法断开与外设的连接,并实现centralManager:didDisconnectPeripheral:error:代理方法处理断开连接的情况。

外设角色操作步骤

  1. 导入框架:同样在项目中导入Core Bluetooth框架。
  2. 初始化CBPeripheralManager
    • 创建CBPeripheralManager实例,定义在类属性中。
    • 实现CBPeripheralManagerDelegate代理协议。
    • 使用initWithDelegate:queue:options:方法初始化CBPeripheralManagerdelegate为当前类实例,queue可以为nil使用主线程,options一般为nil
    • 关键代码示例:
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
  1. 等待外设管理器状态更新:实现peripheralManagerDidUpdateState:代理方法,检查外设管理器的状态,只有当状态为.poweredOn时,才可以进行后续操作。
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    if (peripheral.state == CBPeripheralManagerStatePoweredOn) {
        // 可以开始发布服务等操作
    }
}
  1. 创建服务和特征
    • 使用CBService类创建服务对象,使用CBCharacteristic类创建特征对象。
    • 例如:
CBUUID *serviceUUID = [CBUUID UUIDWithString:@"YOUR_SERVICE_UUID"];
CBService *myService = [[CBService alloc] initWithType:serviceUUID primary:YES];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:@"YOUR_CHARACTERISTIC_UUID"];
CBCharacteristic *myCharacteristic = [[CBCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
  1. 添加服务到外设管理器:将创建好的服务添加到外设管理器,调用addService:方法。
[self.peripheralManager addService:myService];
  1. 处理连接请求:实现peripheralManager:didReceiveReadRequest:peripheralManager:didReceiveWriteRequests:代理方法,处理中心设备的读写请求。
  2. 更新特征值:如果需要主动更新特征值,调用updateValue:forCharacteristic:onSubscribedCentrals:方法通知订阅的中心设备特征值的变化。

关键类

  1. CBCentralManager:用于管理中心角色的蓝牙操作,包括扫描、连接外设等。
  2. CBPeripheral:代表一个被发现的蓝牙外设,通过它可以发现服务、特征,并进行数据交互。
  3. CBService:表示蓝牙设备提供的一个服务,一个外设可以有多个服务。
  4. CBCharacteristic:表示服务中的一个特征,数据的读写操作主要针对特征进行。
  5. CBPeripheralManager:用于管理外设角色的蓝牙操作,包括发布服务、处理连接请求等。

关键方法(已在上述步骤中详细提及部分不再重复)

  1. CBCentralManager的方法
    • scanForPeripheralsWithServices:options::扫描附近的蓝牙外设。
    • connectPeripheral:options::连接特定的蓝牙外设。
    • cancelPeripheralConnection::断开与蓝牙外设的连接。
  2. CBPeripheral的方法
    • discoverServices::发现外设提供的服务。
    • discoverCharacteristics:forService::发现服务中的特征。
    • readValueForCharacteristic::读取特征的值。
    • writeValue:forCharacteristic:type::写入数据到特征。
    • setNotifyValue:forCharacteristic::开启或关闭特征的通知。
  3. CBPeripheralManager的方法
    • addService::将服务添加到外设管理器。
    • updateValue:forCharacteristic:onSubscribedCentrals::更新特征值并通知订阅的中心设备。