Ios CoreBluetooth:如何为许多特性(30-40)设计代码?

Ios CoreBluetooth:如何为许多特性(30-40)设计代码?,ios,architecture,software-design,core-bluetooth,cbperipheral,Ios,Architecture,Software Design,Core Bluetooth,Cbperipheral,我搜索了一下,发现这可能是一个重复的问题: 我的问题是: 我有多个服务,这些服务总共有30-40个特征(是的,我需要所有这些特征…)。 作为处理CoreBluetooth的起点,我总是使用Apple示例代码() 发现和服务/特性处理分为两个类,这只适用于少数特性。但在一门课上处理如此大量的特性并不是我在“好的软件设计”中所理解的 首先想到的是为每个服务创建一个类。但不幸的是,一个CBPeripheral只能同时有一个CBPeripheraldegresponse。这意味着我不能把它分成几个类

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

我的问题是:

我有多个服务,这些服务总共有30-40个特征(是的,我需要所有这些特征…)。 作为处理CoreBluetooth的起点,我总是使用Apple示例代码()

发现和服务/特性处理分为两个类,这只适用于少数特性。但在一门课上处理如此大量的特性并不是我在“好的软件设计”中所理解的

首先想到的是为每个服务创建一个类。但不幸的是,一个CBPeripheral只能同时有一个CBPeripheraldegresponse。这意味着我不能把它分成几个类

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

我也阅读了最后提供的,但它只是描述了基本的工作流程-没有关于正确的设计

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

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

在伪obj-c代码中,dispatcher外围委托如下所示:

// 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];
}

如果中央管理器已关闭,那么最好的解决方案是删除整个外围代理。不要费心重新初始化,而是计划处理。当然,如果需要,您可以通知服务处理程序即将发生的破坏。

首先感谢您的精彩解释。只是为了知道我的理解是否正确:委托保留在管理多个服务处理程序的类中。您将在哪里存储检索到的值?在每个服务处理程序中还是在manager类中?是否使用全局NSNotifications通知视图控制器新检索到的值?是的,修改原始委托以实现dispatcher模式。您可以将引用存储在任何地方,只要确保服务处理程序可以在需要时访问它们。请记住,不要试图缓存它们,核心蓝牙将尽可能为您做到这一点。使用通知是实现松耦合的一种方法,但我更喜欢使用来自ReactiveCocoa的信号。这是一个了不起的图书馆!查看回购协议并阅读文档如果您有任何问题,请打开一个问题或将其张贴在上面。一旦你习惯了它,你会喜欢它的。这是一个很棒的答案,感谢你花时间来写它。一个旁注:我记得当我使用NSNotifications处理这么多数据时,它最终会变成一个冻结的应用程序。通知风暴对于传输数据来说真的不是一个好主意…(很久以前我就这么做了,但我认为这对任何iOS新手来说都是一个重要的信息)