9

skanować dla mojego peryferyjnych tak:Corebluetooth centralny menedżer zwrotna didDiscoverPeripheral dwukrotnie

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

Nie ma problemu, uważam, że obwodowy i są w stanie połączyć się z nim. Jak widać, podaję CBCentralManagerScanOptionAllowDuplicatesKey z bool NO, aby nie zezwalać na więcej niż jedno urządzenie peryferyjne, ale czasami wywołanie zwrotne didDiscoverPeripheral jest uruchamiane dwukrotnie.

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

Czasami dostaję

Discovered 
Already discovered 

jako wyjście w mojej konsoli, a większość czasu tylko komunikat Discovered pokazuje.

W moim delegata obwodowej po raz pierwszy odkryć usług, które następnie wywołać [peripheral discoverCharacteristics i zwrotna zawsze następuje:

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

    } 
} 

Kiedy didDiscoverPeripheral wystąpić dwukrotnie service staje nil w tej metodzie, chociaż peripheral nie jest (UUID, nazwa jest nadal poprawna).

Ponowne uruchomienie telefonu lub zresetowanie ustawień sieciowych powoduje tymczasowe rozwiązanie problemu.

Naprawdę muszę to naprawić! Dziękujemy

+0

Jaki był parametr "nie więcej niż jedno urządzenie", który podałeś? – yuklai

+0

false w CBCentralManagerScanOptionAllowDuplicatesKey – chwi

+0

Domyślam się, że jest on wywoływany dwa razy, gdy siła sygnału jest słaba. –

Odpowiedz

9

Urządzenia mogą zwracać dodatkowe dane podczas reklam. Mogą one przychodzić w osobnych pakietach, przybywając w różnym czasie. W tym przypadku didDiscoverPeripheral jest wywoływany jako pierwszy, gdy urządzenie jest początkowo widoczne, a następnie ponownie, gdy dostępne będą dla niego dodatkowe informacje.

CBCentralManagerScanOptionAllowDuplicatesKey jest inny. Informuje CoreBluetooth, czy chcesz otrzymywać zduplikowane wyniki, gdy urządzenie reklamuje się ponownie. Nie zapobiega to wielokrotnym wywołaniom didDiscoverPeripheral dla tej samej sekwencji wykrywania; zapobiega to wielokrotnym sekwencjom wykrywania.

Źródło: http://lists.apple.com/archives/bluetooth-dev/2012/Apr/msg00047.html (przedstawiciel Apple na urządzeniu Bluetooth).

+0

Dziękuję. Czy masz jakieś pomysły, jak to rozwiązać? – chwi

+0

@Wilhelmsen: Co trzeba rozwiązać? Po prostu śledź już identyfikatory UUID, które już widziałeś. –

+0

Próbowałem odpowiedzi Mike'a, czy to też nie rejestruje UUID? Jestem całkiem nowy w tym, więc jeśli masz jakieś dalsze wskazówki, jak programowo osiągnąć to, byłbym naprawdę wdzięczny! W każdym razie, bardzo dziękuję za twoje informacje. – chwi

6

Nie sądzę, aby ten parametr spełniał Twoje oczekiwania. Zrozumienie tego, w jaki sposób jest on stosowany w próbkach Apple, takich jak termometr zdrowotny, polega na tym, że włączenie tej flagi umożliwia wykrywanie wielu różnych urządzeń peryferyjnych z tym samym UUID. Na przykład, jeśli chcesz napisać aplikację, która patrzy na cztery różne termometry w tym samym pomieszczeniu i znajduje wszystkie z nich, potrzebujesz parametru, aby skanowanie nie zakończyło się po znalezieniu pierwszego.

w kodzie, Apple unika duplikatów tak:

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

Jeśli urządzenie już istnieje w tablicy, nie dodaje się po raz drugi.

Byłoby miło, gdyby dokumentacja była bardziej przejrzysta w tym punkcie. Przyznaję, że zgaduję na podstawie tego, jak parametr jest używany w kontekście.

+0

Dziękuję! czy powinno to przejść do mojej metody didDiscoverPeripheral? – chwi

+0

Tak, właśnie to Apple tak ujął. Zobacz http://developer.apple.com/library/mac/#samplecode/HealthThermometer/Listings/HealthThermometerClient_HealthThermometerClientAppDelegate_m.html#//apple_ref/doc/uid/DTS40011370-HealthThermometerClient_HealthThermometerClientAppDelegate_m-DontLinkElementID_4 dla pełnego źródła. – Mike

+0

Myślę, że to rozwiązało. Nie byłem w stanie powtórzyć tego w jaki sposób: D Postawię odpowiedź na moje pytanie tylko po to, aby się upewnić. Bardzo dziękuję – chwi