核心蓝牙:如何为许多特征(30 - 40)设计代码



我搜索了一下,发现这可能是一个重复的问题:

同一设备的多个CBPeripheral设备

我的问题是:

我有多个服务,它们总共有大约 30-40 个特征(是的,我需要所有这些......作为处理CoreBlues的起点,我一直使用Apple示例代码(CoreBluetooth 温度传感器)。

发现和服务/特征处理分为两类,这仅适用于少数特征。但是在一个类中处理如此大量的特征并不是我在"好的软件设计"下所理解的。

人们想到的第一个想法是为每个服务创建一个类。但不幸的是,一个CBPeripheral只能同时拥有一个CBPeripheralDelegate这意味着我不能将其分为几类。

如果BLE是获取如此大量数据的正确技术,我们不必开始讨论 - 事实并非如此。但是有些制造商使用BLE所以他们不必为MFi程序而烦恼......

我还阅读了最终提供的 CoreBluetooth 编程指南,但它只描述了基本的工作流程 - 没有关于正确设计的内容.

我正在寻找一种不错的设计方法。您可能对示例代码有任何建议、提示或链接?提前非常感谢!

将逻辑分解为几个自包含类总是好的设计。您绝对应该尝试根据服务或其他类别对代码进行分组。即使外围设备只有一个委托,您也可以轻松实现调度程序模式,在该模式中注册各种服务实现和选择键(实际上是服务对象)并将调用调度到指定的服务处理程序。如果服务类实现CPPeripheralDelegate协议,那么此设计将允许您在需要时单独测试/重用每个服务,只需对代码进行最少的更改。

在伪 obj-c 代码中,调度程序外围委托如下所示:

// The ivar/property serving as the registry
NSMutableDictionary *registeredHandlers = [[NSMutableDictionary alloc] init];
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
  // for each service create an instance of its handler class and
  // add them to the registered handlers
  for (CBService *service : peripheral.services) {
    if (!registeredHandlers[service]) { // don't reinitialize if not needed
      ExtendedCBPeripheralDelegate *serviceHandler = [self instantiateHandlerForService:service];
      [registeredHandlers setObject:serviceHandler forKey:service];
      [serviceHandler discoverCharacteristics]; // make this functionality self contained for the service
    }
  }
}

在服务或特征相关的回调中,应实现调度。举个例子:

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
  ExtendedCBPeripheralDelegate *serviceHandler = registeredHandlers[service];
  [serviceHandler peripheral:peripheral didDiscoverCharacteristicsForService:service error:error];
}
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
  ExtendedCBPeripheralDelegate *serviceHandler = registeredHandlers[characteristic.service];
  [serviceHandler peripheral:peripheral didWriteValueForCharacteristic:characteristic error:error];
}

如果中央管理器断电,则最佳解决方案是删除整个外围委托。不要为重新初始化而烦恼,而是计划处置。当然,如果需要,您可以通知服务处理程序即将发生的销毁。

最新更新