Corebluetooth中央管理器回调确实发现了两次外围设备

时间:2012-07-19 09:09:22

标签: iphone objective-c callback core-bluetooth bluetooth-lowenergy

我像这样扫描我的外围设备:

NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] 
                                                            forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
        // Scan for peripherals with given UUID
        [cm scanForPeripheralsWithServices:[NSArray arrayWithObject:HeliController.serviceUUID] options:scanOptions]

没问题,我找到外围设备并能够连接到它。如您所见,我将CBCentralManagerScanOptionAllowDuplicatesKeybool NO一起提供给不允许多个外围设备,但有时didDiscoverPeripheral回调会触发两次。

- (void) centralManager:(CBCentralManager *)central 
  didDiscoverPeripheral:(CBPeripheral *)peripheral 
  advertisementData:(NSDictionary *)advertisementData 
               RSSI:(NSNumber *)RSSI 
{        
if(!discovered){
    discovered = YES;
    NSLog(@"Discovered");

    [cm stopScan];

    [scanButton setTitle:@"Connect" forState:UIControlStateNormal];
}
else if(discovered){
    discovered = YES
    NSLog(@"Already discovered");
}
}

有时我会

Discovered
Already discovered

作为我的控制台中的输出,并且大多数时间只显示Discovered消息。

在我的外围代理中,我首先发现服务,然后调用[peripheral discoverCharacteristics并且始终发生回调:

- (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{

NSLog(@"Did discover characteristic for service %@", [service.peripheral UUID]);

for(CBCharacteristic *c in [service characteristics]){
    // We never get here when peripheral is discovered twice
    if([[c UUID] isEqual:myCharacteristicUUID]){

        NSLog(@"Found characteristic");

        self.throttleCharacteristic = c;

    }
}

didDiscoverPeripheral出现两次时,service在此方法中变为nil,即使peripheral不是(UUID,名称仍然正确)。

重新启动手机或重置网络设置可以暂时解决问题。

我真的需要解决这个问题!谢谢

2 个答案:

答案 0 :(得分:10)

广告时,设备可能会返回其他数据。这些可以分开到达,在不同时间到达。在这种情况下,在最初看到设备时首先调用didDiscoverPeripheral,然后在有可用的附加信息时再次调用。

CBCentralManagerScanOptionAllowDuplicatesKey是不同的。它告诉CoreBluetooth当设备再次通告自己时是否要接收重复的结果。它不会阻止多次调用didDiscoverPeripheral用于相同的发现序列;它会阻止它重复发现序列。

来源:http://lists.apple.com/archives/bluetooth-dev/2012/Apr/msg00047.html(蓝牙-dev上的Apple代表)。

答案 1 :(得分:6)

我不认为这个参数符合你的想法。通过研究如何在健康温度计等Apple样本中使用它,我的理解是打开此标志可以发现具有相同UUID的多个不同外围设备。例如,如果你想编写一个应用程序来查看同一个房间里的四个不同的温度计,并找到所有这些温度计,你需要参数,这样扫描在找到第一个之后就不会停止。

在他们的代码中,Apple避免重复这样的内容:

NSMutableArray *peripherals = [self mutableArrayValueForKey:@"thermometers"];
if( ![self.thermometers containsObject:peripheral] )
    [peripherals addObject:peripheral];

如果设备已存在于阵列中,则不会再次添加。

如果文档在这一点上更清楚,那就太好了。我承认我正在根据参数在上下文中的使用方式进行猜测。