CoreBluetooth: How to design code for many characteristics (30 - 40)?

徘徊边缘 提交于 2019-12-03 12:08:25

Breaking out logic into several self contained classes is always good design. You should definitely try to group your code according to services or other categories. Even though the peripheral has only a single delegate, you can easily implement the dispatcher pattern where you register the various service implementations and selection keys (practically the service objects) and dispatch the call to the designated service handler. If the service classes implement the CPPeripheralDelegate protocol, then this design will allow you to test/reuse each service separately if you need to with minimal changes in the code.

In pseudo obj-c code the dispatcher peripheral delegate would look like as follows:

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

In service or characteristic related callbacks the dispatching should be implemented. An example:

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

If the central manager is powered off, then the best solution is to drop the whole peripheral delegate. Don't bother with reinitialization, rather plan for disposal. Of course, if needed, you can notify the service handlers of the imminent destruction.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!