Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

iphone - Corebluetooth central manager callback didDiscoverPeripheral twice

I scan for my peripheral like this:

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

No problem there, I find the peripheral and are able to connect to it. As you can see I give it CBCentralManagerScanOptionAllowDuplicatesKey with bool NO to not allow for more than one peripheral, but sometimes the didDiscoverPeripheralcallback fires twice.

- (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");
}
}

Some times I get

Discovered
Already discovered

as output in my console, and most of the times only the Discoveredmessage shows.

In my peripheral delegate I first discover services, which then call [peripheral discoverCharacteristics and the callback always occurs:

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

    }
}

When didDiscoverPeripheral occur twice, service becomes nilin this method, even though peripheral is not (UUID, name is still correct).

Rebooting the phone or resetting the network settings fixes the problem temporarily.

I really need to get this fixed! Thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Devices may return additional data while advertising. These may arrive in separate packets, arriving at different times. In this case, didDiscoverPeripheral is called first when the device is initially seen, and then again when additional information becomes available for it.

CBCentralManagerScanOptionAllowDuplicatesKey is different. It tells CoreBluetooth whether you want to receive duplicate results when the device advertises itself again. It doesn't prevent multiple calls to didDiscoverPeripheral for the same discovery sequence; it prevents it for repeated discovery sequences.

Source: http://lists.apple.com/archives/bluetooth-dev/2012/Apr/msg00047.html (the Apple rep on bluetooth-dev).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...