我搜索了一下,发现这可能是一个重复的问题:
Multiple CBPeripheral's for same device
我的问题是:
我有多项服务,它们共有 30-40个特征(是的,我需要所有这些......)。 作为处理CoreBluetooth的起点,我总是使用Apple示例代码(CoreBluetooth Temperature Sensor)。
发现和服务/特征处理分为两类,这只适用于几个特征。但是在一个类中处理这么多的特性并不是我在“良好的软件设计”中理解的。
首先想到的是为每个服务创建一个类。但不幸的是, CBPeripheral 可以同时拥有一个 CBPeripheralDelegate 。这意味着我不能把它分成几个类。
(如果BLE是获取这些数据的正确技术,我们不必开始讨论 - 事实并非如此。但是有些制造商使用BLE,所以他们不必麻烦MFi计划...... )
我还阅读了最终提供的CoreBluetooth Programming Guide,但它只描述了基本的工作流程 - 没有关于正确的设计。
我正在寻找一种不错的设计方法。您可能有任何建议,提示或示例代码链接? 非常感谢提前!
答案 0 :(得分:9)
将逻辑分解为几个自包含的类总是很好的设计。您一定要尝试根据服务或其他类别对代码进行分组。即使外围设备只有一个委托,您也可以轻松实现调度程序模式,您可以在其中注册各种服务实现和选择键(实际上是服务对象),并将调用分派给指定的服务处理程序。如果服务类实现了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];
}
如果中央管理器已关闭,那么最佳解决方案是删除整个外围代理。不要为重新初始化而烦恼,而是计划处置。当然,如果需要,您可以通知服务处理人员即将发生的破坏。