Запуск iPhone в качестве iBeacon в фоновом режиме
Возможно ли запустить iOS 7-устройство в качестве периферийного устройства Bluetooth LE (iBeacon) и рекламировать его в фоновом режиме? Я смог получить его для рекламы на переднем плане с приведенным ниже кодом и увидеть его с другого устройства iOS, но как только я вернусь на главный экран, он прекратит рекламу. Я добавил bluetooth-периферийный режим фона в plist, но это, похоже, не помогло, хотя я получаю подсказку, говорящее, что устройство хочет использовать bluetooth в фоновом режиме. Я что-то делаю неправильно или это невозможно в iOS 7?
peripManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
return;
}
NSString *identifier = @"MyBeacon";
//Construct the region
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:identifier];
//Passing nil will use the device default power
NSDictionary *payload = [beaconRegion peripheralDataWithMeasuredPower:nil];
//Start advertising
[peripManager startAdvertising:payload];
}
Вот код, который находится на конце приема/прослушивания:
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region
{
//Check if we have moved closer or farther away from the iBeacon…
if (beacons.count > 0) {
CLBeacon *beacon = [beacons objectAtIndex:0];
switch (beacon.proximity) {
case CLProximityImmediate:
[self log:[NSString stringWithFormat:@"You're Sitting on it! %li", (long)beacon.rssi]];
break;
case CLProximityNear:
[self log:[NSString stringWithFormat:@"Getting Warmer! %li", (long)beacon.rssi]];
break;
default:
[self log:[NSString stringWithFormat:@"It around here somewhere! %li", (long)beacon.rssi]];
break;
}
}
}
Ответы
Ответ 1
Стандартные объявления CoreBluetooth могут транслироваться, когда приложение находится в фоновом режиме, но не в том случае, если они были запущены с помощью словаря CLBeaconRegion
. Обходной путь состоит в том, чтобы полностью расколоть структуру CoreLocation и создать собственную "инфраструктуру" близости, используя только CoreBlueTooth.
Вам по-прежнему необходимо использовать соответствующие спецификаторы фона в файле Info.plist(например, bluetooth-peripheral
и bluetooth-central
).
Код выглядит примерно так:
1) создайте стандартное периферийное объявление, используя CBPeripheralManager
NSDictionary *advertisingData = @{CBAdvertisementDataLocalNameKey:@"my-peripheral",
CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:identifier]]};
// Start advertising over BLE
[peripheralManager startAdvertising:advertisingData];
2) используйте CBCentralManager
для сканирования этой службы с использованием указанного UUID.
NSDictionary *scanOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@(YES)};
NSArray *services = @[[CBUUID UUIDWithString:identifier]];
[centralManager scanForPeripheralsWithServices:services options:scanOptions];
3) в методе CBCentralManagerDelegate
didDiscoverPeripheral
, прочитайте значение RSSI
рекламы.
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"RSSI: %d", [RSSI intValue]);
}
4) Переведите значения RSSI на расстояние.
- (INDetectorRange)convertRSSItoINProximity:(NSInteger)proximity
{
if (proximity < -70)
return INDetectorRangeFar;
if (proximity < -55)
return INDetectorRangeNear;
if (proximity < 0)
return INDetectorRangeImmediate;
return INDetectorRangeUnknown;
}
Я обнаружил, что мне нужно "облегчить" или "усреднить" значения RSSI, чтобы получить что-либо работоспособное. Это не отличается от того, когда вы работаете с данными датчиков (например, данными акселерометра).
У меня есть эта концепция, полностью работающая в надежде опубликовать ее где-то в какой-то момент.
Кроме того, если вы застряли, используйте docs (Core Bluetooth Programming Guide).
Обновление: A полный пример кода включен в Github. Я работал над этим как часть проекта связанного с работой.
Обновление # 2: Apple выпустит основные улучшения в отношении поведения iBeacon для iOS7.1
Ответ 2
Вы можете почувствовать запах статьи iBeacon?, обсуждая как использование Оценки, так и рекламу с компьютеров Mac и iOS. Вам нужно проверить возможность "Акты в качестве аксессуара Bluetooth LE" в целевой программе.
Ответ 3
Нет, устройства iOS рекламируют только iBeacon, когда приложение, которое делает рекламу, запускается на переднем плане. поэтому, если вы переключаетесь на другое приложение или устройство переходит в режим сна, реклама останавливается.
Конечно, если вы действительно хотите, чтобы реклама продолжалась, отключите таймер простоя и сделайте Guided Access, чтобы устройство iOS не переходило в режим сна, и никто не может переключиться на другое приложение.
Ответ 4
Я также надеюсь, что смогу настроить мое (тестовое) приложение для рекламы iBeacon с фона. Документы в ключе UIBackgroundModes info.plist предполагают, что bluetooth-периферийный ключ может работать, но, похоже, он этого не делает. (Я только что проверил это несколько минут назад.)
То, что я делаю сейчас, - отключить таймер простоя, как предлагает RawMean, а затем установить яркость экрана на 0. Наконец, когда мое тестовое приложение действует как iBeacon, я добавляю обработчик события shake, который снова загорается экран в течение 30 секунд. Уменьшение яркости экрана при низком уровне помогает немного уменьшить расход батареи.