Iphone Corebluetooth中央管理器回调DidDiscovery外围设备两次

Iphone Corebluetooth中央管理器回调DidDiscovery外围设备两次,iphone,objective-c,callback,core-bluetooth,bluetooth-lowenergy,Iphone,Objective C,Callback,Core Bluetooth,Bluetooth Lowenergy,我像这样扫描我的外设: NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // Scan for peripherals

我像这样扫描我的外设:

NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] 
                                                            forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
        // Scan for peripherals with given UUID
        [cm scanForPeripheralsWithServices:[NSArray arrayWithObject:HeliController.serviceUUID] options:scanOptions]
NSMutableArray *peripherals = [self mutableArrayValueForKey:@"thermometers"];
if( ![self.thermometers containsObject:peripheral] )
    [peripherals addObject:peripheral];
没问题,我找到了外设并且可以连接到它。如您所见,我使用
bool NO
CBCentralManagerScanOptionAllowDuplicatesKey
设置为不允许使用多个外围设备,但有时会触发两次
didDiscoveryPeripal
回调

- (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
作为我的控制台中的输出,大多数情况下只显示
发现的
消息

在我的外围设备代理中,我首先发现服务,然后调用
[外围设备发现特性
,回调总是发生:

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

    }
}
didiscoverperipheral
发生两次时,
service
在此方法中变为
nil
,即使
peripheral
不是(UUID,名称仍然正确)

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


我真的需要把它修好!谢谢你,我不认为这个参数会像你认为的那样。通过观察它在苹果样本(如健康温度计)中的使用,我的理解是,打开这个标志可以发现具有相同UUID的多个不同外设。例如,如果你想编写一个在同一个房间里看四个不同的温度计,找到所有的温度计,你需要参数,这样在找到第一个温度计后扫描不会停止

在他们的代码中,苹果避免了类似这样的重复:

NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] 
                                                            forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
        // Scan for peripherals with given UUID
        [cm scanForPeripheralsWithServices:[NSArray arrayWithObject:HeliController.serviceUUID] options:scanOptions]
NSMutableArray *peripherals = [self mutableArrayValueForKey:@"thermometers"];
if( ![self.thermometers containsObject:peripheral] )
    [peripherals addObject:peripheral];
如果阵列中已存在该设备,则不会再次添加该设备


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

设备在广告时可能会返回额外的数据。这些数据可能会在不同的时间以不同的包到达。在这种情况下,当最初看到设备时,会首先调用DidDiscoveryPeripaln、 然后,当其他信息可用时,再次进行此操作

CBCentralManagerScanOptionAllowDuplicatesKey不同。它告诉CoreBluetooth当设备再次播发自身时,是否要接收重复结果。它不阻止对同一发现序列多次调用DidDiscoveryPeripal;它阻止重复发现序列


来源:(bluetooth dev上的苹果代表)。

什么是“最多一台设备”你给出的参数?CBCentralManager上为false OptionalLowDuplicates我猜它在信号强度差时会被调用两次。我将在周一尝试这一理论,但根据我的经验,如果它发生过一次,除非我重新启动电话,否则我无法让它再次工作。这与信号强度无关谢谢!这应该纳入我的DidDiscoveryPeripheral方法吗?是的,反正苹果就是这么说的。请看完整的来源。我实际上认为这解决了它。我还没有能够复制它。如何:D我会就我的问题发表一个答案,只是为了澄清。非常感谢。这是错误的。不同的外设将永远不会有相同的UUID;如果有四个温度计,有四个UUID。设置CBCentralManagerScanOptionAllowDuplicatesKey允许多次返回同一设备,因此只要设备正在播放广告且您尚未连接到它,您就会反复收到DidDiscoveryPeripheral回调。将其设置为否(默认值)表示您只想第一次看到它。外围设备UUID和服务UUID之间存在差异。scanForPeripheralsWithServices:options:使用服务UUID,这可能会可以在多个提供相同信息的设备(如温度计)之间复制。设备本身的UUID(此调用中未使用)是另一个问题。我假设但不确定它们是唯一的。原始帖子没有明确说明这一点。@Wilhelmsen:需要解决什么?只需跟踪UUID即可你已经看到了。我尝试了@Mike的答案,这不也是跟踪UUID的吗?我在这方面是相当新的,所以如果你对如何通过编程实现这一点有任何进一步的提示,我将非常感激!无论如何,非常感谢你提供的信息DidDiscoveryPeripal返回CBPeripheral对象。这些对象中的每一个都有UUID属性te,可用于跟踪同一外围对象上第一次和第二次回调发生的时间。该“附加数据”被称为扫描响应,外围设备仅在中央设备请求时发送该附加数据。在这种情况下,CoreBooth会自动为其发现的每个设备请求该附加数据。我一直在寻找该数据,但对此我不确定。如何检查我们第二次发现外围设备时是否有附加数据?在我的情况下,是广告isementData是相同的。