Рекламируйте, сканируйте и отслеживайте iBeacon и CBPeripheral одновременно

Я одновременно рекламирую периферийные устройства BLE и маяк, объединенные в одном NSDictionary и рекламируемые тем же CBPeripheralManager. В том же приложении я сканирую периферийные устройства BLE и отслеживаю маяк.

Это не работает - Одновременно реклама периферийного устройства и маяка, кажется, вызывает странный конфликт. На переднем плане будет обнаружен маяк (вход в регион), но обратные вызовы для CBPeripheral не срабатывают. Когда устройство A выполняет фоновое задание для приложения, периферийные обратные вызовы запускаются в приложении, работающем на устройстве B, и сервисный и характеристический запрос выполняется, как и ожидалось.

Поведение предполагает, что реклама для маяка блокирует рекламу для периферийного устройства, когда на переднем плане, но периферийная реклама эффективна, когда приложение находится в фоновом режиме.

Рекламный код выглядит следующим образом:

    NSDictionary *adUUIDs = [[NSDictionary alloc] initWithObjectsAndKeys:@"CNT100A", @"kCBAdvDataLocalName", _serviceUUIDs, @"kCBAdvDataServiceUUIDs", nil];

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"328204DB-5128-40B4-9C73-65DF66899945"];
    CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:1 identifier:@"com.aurl.id"];
    NSDictionary *beaconData = [beaconRegion peripheralDataWithMeasuredPower:nil];

    NSMutableDictionary *advert = [NSMutableDictionary dictionaryWithDictionary:beaconData];
    [advert addEntriesFromDictionary:adUUIDs];

    [_adManager startAdvertising:advert];

Который производит это:

(lldb) po advert
{
    kCBAdvDataAppleBeaconKey = <328204db 512840b4 9c7365df 66899945 00010001 c8>;
    kCBAdvDataLocalName = CNT100A;
    kCBAdvDataServiceUUIDs =     (
        "5351CAD0-B1CE-4E38-8673-76D05124E915",
        "E7A48922-5D43-4237-821D-D710E69EE1CD"
    );
}

Если я удаляю периферийное устройство или элемент рекламы маяка из словаря перед вызовом startAdvertising, приложение ведет себя нормально.

Мое сканирование CBCentralManager называется следующим образом:

[_searchManager scanForPeripheralsWithServices:serviceUUIDs options:@{CBCentralManagerScanOptionSolicitedServiceUUIDsKey: serviceUUIDs, CBCentralManagerScanOptionAllowDuplicatesKey:continuousSearch}];

И мой мониторинг региона является стандартным:

    NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"328204DB-5128-40B4-9C73-65DF66899945"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:1 minor:1 identifier:@"com.aurl.id"];
    self.beaconRegion.notifyEntryStateOnDisplay = YES;

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    [self.locationManager requestAlwaysAuthorization];
    [self.locationManager startMonitoringForRegion:self.beaconRegion];

Я пытался заставить это работать дольше, чем я хочу признать... Я неправильно понял что-то простое? Apple ограничивает некоторые функции в этой области?

1 ответ

К сожалению, из вашего описания видно, что вы не можете рекламировать iBeacon и другую периферийную службу одновременно iOS.

Это не супер удивительно. Маяки рекламируются с частотой 10 Гц, и хотя большинство чипов Bluetooth допускают более частую передачу, они обычно не поддерживают чередование на уровне чипа. Это означает, что если iOS хочет поддерживать одновременную трансляцию обоих типов рекламы на всех чипах (на всех моделях iPhone и iPad), то для этого потребуется специальный код. Похоже на меня это не так.

Чтобы быть понятным, у меня нет специальной информации о внутренней реализации трансляции нескольких типов рекламы одновременно на iOS. Но я знаю по своему опыту, что для того, чтобы делать то, что вы хотите, нужно прыгать через специальные обручи на низком уровне, поэтому вполне вероятно, что iOS просто не позволяет этого.

Другие вопросы по тегам