Подтвердить что ты не робот

Сохранение и восстановление состояния ядра Bluetooth не работает, не удается перезапустить приложение в фоновом режиме

Я пытаюсь сделать базовое bluetooth пробудить приложение, даже если оно не работает.

Как заявила Apple: "Поскольку сохранение и восстановление состояния встроено в Core Bluetooth, ваше приложение может выбрать эту функцию, чтобы попросить систему сохранить состояние ваших центральных и периферийных менеджеров ваших приложений и продолжить выполнение определенных функций Bluetooth- связанных с ними, даже когда ваше приложение больше не работает. Когда одна из этих задач завершается, система перезагружает ваше приложение в фоновом режиме и дает вашему приложению возможность восстановить свое состояние и соответствующим образом обработать событие".

Я добавил следующий код, чтобы выбрать эту функцию:

 myCentralManager =
        [[CBCentralManager alloc] initWithDelegate:self queue:nil
         options:@{ CBCentralManagerOptionRestoreIdentifierKey:
         @"myCentralManagerIdentifier" }];

Но обратные вызовы при пробуждении приложения никогда не запускались.

-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
}

-(void)centralManager:(CBCentralManager *)central
      willRestoreState:(NSDictionary *)state {
}

Эти два никогда не вызываются.

Как я тестирую эту функцию пробуждения:

  • Я добавляю "bluetooth central" в фоновом режиме в info.plist, поэтому BLE работает в фоновом режиме.

  • запустите centralManager в моем iphone №1. начать сканирование.

  • нажмите домой и выходите, играйте в тяжелую игру с памятью, в журнале отладки я увижу: "Завершена из-за давления памяти. Процесс завершен с кодом выхода 0". Это должно имитировать, как система ios завершает фоновое приложение из-за давления памяти.

  • запустите маяк с другим iphone №2 и начните трансляцию.

  • результат: эти вызовы callback никогда не вызываются.

Любые идеи, почему это не работает? Если это проблема API, есть ли какой-либо другой подход для возобновления вашего приложения в фоновом режиме с помощью BLE, когда ваш телефон приближается к маяку BLE? Я попытался использовать ibeacon для пробуждения приложения, но центральный диспетчер bluetooth не позволит вам подключиться к ibeacon в фоновом режиме.

Спасибо!

4b9b3361

Ответ 1

CoreBluetooth восстановление состояния применяется только к соединениям и периферийным событиям. Единственное, что полагается на сканирование, в настоящее время не поддерживается.

Ответ 2

Когда вы нажимаете кнопку "Дом", чтобы отправить приложение в фоновый режим, оно приостанавливается и может обрабатывать делегаты Bluetooth и работать в фоновом режиме в течение 10 секунд, эту функцию можно достичь исключительно "добавьте bluetooth в фоновом режиме в info.plist", и не использует государственное сохранение и восстановление.

Если ваше приложение завершено IOS, из-за нехватки памяти, он больше не может обрабатывать делегатов Bluetooth. В этом случае, если вы использовали State Preservation and Restoration, ваше приложение может быть перезапущено в фоновый режим для повторного запуска, а также всего за 10 секунд. Через 10 секунд он переместится в приостановленное состояние. Только в этой ситуации может запускаться CBCentralManager willRestoreState.

Вы можете добавить код

kill (getpid(), SIGKILL);

к действию кнопки, когда вы нажмете кнопку, ваше приложение будет завершено IOS, как убитое давлением памяти, а затем будет вызвано "willRestoreState".

Удачи.

Ответ 3

У меня также есть эта проблема с фоновым сканированием для периферийных устройств с известной услугой UUIDs. Возможно, это ошибка в iOS. Я обнаружил, что iOS перезапускает приложение, когда обнаруживает периферийное устройство, что можно увидеть, наблюдая за выходом консоли из диспетчера устройств в XCode. Вызывается делегат didFinishLaunchingWithOptions, но вызов делегата CBCentralManager's willRestoreState задерживается до тех пор, пока пользователь вручную не выведет приложение на передний план.

Как будто цикл события в основном потоке не запускается, даже если приложение запущено. Например, при добавлении кода:

dispatch_async(dispatch_get_main_queue(), ^{
  NSLog(@"Hello from the main thread");
});

для делегата didFinishLaunchingWithOptions, сообщение не отображается в консоли отладки, пока приложение не переместится на передний план.

Моим обходным путем является использование отдельной очереди, выполняемой в отдельном потоке, вместо передачи queue:nil при создании CBCentralManager. Таким образом, делегаты вызываются, пока приложение все еще находится в фоновом режиме.