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.