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

I searched a bit and just found this as a possible duplicate question:

Multiple CBPeripheral for one device

My problem:

I have several services that all have about 30-40 characteristics (yes, I need all of them ...). As a starting point for working with CoreBluetooth, I always used the Apple code sample ( CoreBluetooth temperature sensor ).

Detection and maintenance / feature processing is divided into two classes, and this is great for multiple features. But processing this huge amount of features in one class is not what I mean by “good software”.

The first idea that comes to mind is to create one class for each service. But unfortunately, CBPeripheral can have one CBPeripheralDelegate at a time. This means that I cannot split it into several classes.

(We don’t need to start a discussion if BLE is the right technology to get this amount of data - it’s not. But there are manufacturers who use BLE, so they don’t have to bother with the MFi program ...)

I also read, finally, the CoreBluetooth Programming Guide , but it just describes the basic workflows - nothing about the right design.

I am looking for a good design. Can you have suggestions, tips or links to sample code? Thank you very much in advance!

+8
ios architecture software-design core-bluetooth cbperipheral
source share
1 answer

Breaking the logic into several independent classes is always a good design. You should definitely try to group your code according to services or other categories. Despite the fact that the peripheral device has only one delegate, you can easily implement the dispatcher template in which you register various service implementations and selection keys (practically service objects) and send a call to the designated service handler. If service classes implement the CPPeripheralDelegate protocol, then this project will allow you to test / reuse each service separately, if you need it with minimal changes in the code.

In the pseudo object code, the peripheral delegate delegate will look like this:

 // 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 feature-related callbacks, scheduling must be implemented. 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 dispatcher is disabled, the best solution is to reset the entire peripheral delegate. Don't worry about reinitializing; rather, plan for deletion. Of course, if necessary, you can notify service handlers of imminent destruction.

+8
source share

All Articles