9

scanne ich für meine Peripherie wie folgt aus:Corebluetooth zentralen Manager Rückruf didDiscoverPeripheral zweimal

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

Kein Problem gibt, finde ich die peripheren und sind in der Lage, eine Verbindung herzustellen. Wie Sie sehen können gebe ich es CBCentralManagerScanOptionAllowDuplicatesKey mit bool NO nicht für mehr als ein Peripheriegerät zuzulassen, aber manchmal wird der Rückruf zweimal ausgelöst.

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

Einige Male ich

Discovered 
Already discovered 

als Ausgabe in meiner Konsole, und die meisten der Zeit nur die Discovered Nachricht zeigt.

In meinem peripheren Delegierten entdecken I ersten Dienste, die dann [peripheral discoverCharacteristics rufen und der Rückruf erfolgt immer:

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

    } 
} 

Wenn didDiscoverPeripheral zweimal auftreten, service wird nil in diesem Verfahren, obwohl peripheral nicht (UUID ist, Name ist immer noch korrekt).

Durch einen Neustart des Telefons oder das Zurücksetzen der Netzwerkeinstellungen wird das Problem vorübergehend behoben.

Ich muss wirklich das behoben werden! Danke

+0

Was war der Parameter "nicht mehr als ein Gerät", den Sie angegeben haben? – yuklai

+0

false auf CBCentralManagerScanOptionAllowDuplicatesKey – chwi

+0

Meine Vermutung ist, dass es zweimal aufgerufen wird, wenn die Signalstärke schlecht ist. –

Antwort

9

Geräte können während der Werbung zusätzliche Daten zurückgeben. Diese können in getrennten Paketen ankommen, die zu unterschiedlichen Zeiten ankommen. In diesem Fall wird didDiscoverPeripheral zuerst aufgerufen, wenn das Gerät zuerst angezeigt wird, und dann erneut, wenn zusätzliche Informationen dafür verfügbar sind.

CBCentralManagerScanOptionAllowDuplicatesKey ist anders. Er teilt CoreBluetooth mit, ob Sie doppelte Ergebnisse erhalten möchten, wenn sich das Gerät erneut meldet. Es verhindert nicht mehrere Aufrufe von didDiscoverPeripheral für dieselbe Erkennungssequenz. es verhindert es für wiederholte Erkennungssequenzen.

Quelle: http://lists.apple.com/archives/bluetooth-dev/2012/Apr/msg00047.html (der Apple rep auf Bluetooth-dev).

+0

Danke. Haben Sie Ideen, wie Sie das lösen können? – chwi

+0

@Wilhelmsen: Was muss gelöst werden? Verfolgen Sie nur die UUIDs, die Sie bereits gesehen haben. –

+0

Ich versuchte @ Mikes Antwort, verfolgt das nicht auch UUIDs? Ich bin ziemlich neu in diesem Bereich. Wenn Sie weitere Hinweise dazu haben, wie dies programmatisch zu erreichen ist, wäre ich wirklich dankbar! Wie auch immer, vielen Dank für Ihre Informationen – chwi

6

Ich glaube nicht, dass dieser Parameter tut, was Sie denken, dass es tut. Wenn ich mir anschaue, wie es in Apple-Proben wie dem Gesundheitsthermometer verwendet wird, kann ich durch Aktivieren dieses Flags mehrere verschiedene Peripheriegeräte mit derselben UUID erkennen. Wenn Sie zum Beispiel eine App schreiben möchten, die vier verschiedene Thermometer im selben Raum betrachtet und alle findet, benötigen Sie den Parameter, damit der Scan nach dem Auffinden des ersten nicht stoppt.

In ihrem Code vermeidet Apple-Duplikate wie folgt aus:

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

Wenn das Gerät bereits in der Anordnung vorhanden ist, wird es kein zweites Mal hinzugefügt.

Es wäre schön, wenn die Dokumentation in diesem Punkt klarer wäre. Ich gebe zu, ich rate, basierend darauf, wie der Parameter im Kontext verwendet wird.

+0

Thank you! sollte dies in meine didDiscoverPeripheral-Methode gehen? – chwi

+0

Ja, das ist, wo Apple es sowieso gesagt hat. Siehe http://developer.apple.com/library/mac/#samplecode/HealthThermometer/Listings/HealthThermometerClient_HealthThermometerClientAppDelegate_m.html#//apple_ref/doc/uid/DTS40011370-HealthThermometerClient_HealthThermometerClientAppDelegate_m-DontLinkElementID_4 für die gesamte Quelle. – Mike

+0

Ich denke tatsächlich, dass es gelöst hat. Ich konnte es nicht wiederholen, wie: D Ich werde eine Antwort auf meine Frage posten, nur um zu klären. Vielen Dank – chwi