13

Я пытаюсь сделать базовое 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 { 
} 

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

Путь я тестирую эту функцию Просыпайтесь:

  1. добавить «Bluetooth центральный» в фоновом режиме в info.plist, так что BLE работает в фоновом режиме.

  2. стартовый центральный менеджер в моем iphone № 1. начать сканирование.

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

  4. Запустите маячок с другим iphone №2 и начните вещание.

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

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

Спасибо!

ответ

2

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

+0

Спасибо tdevoy, любое обходное решение для перезапуска приложения с помощью BLE? – woof

+1

Здравствуйте, @tdevoy, пожалуйста, любезно разработайте периферийные события. – raghul

3

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

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

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

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

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

+0

Как вам это удается? У меня такая же проблема, я не смог вызвать методы делегата в фоновом режиме. –

12

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

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

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

убить (GETPID(), SIGKILL);

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

Удачи.

+0

Кто-нибудь подтвердил, что это действительно работает с кодом? Если да, этот метод будет намного быстрее, чем использование типичных приложений BackgroundKiller. – Etan

+2

@ Etan Это действительно работает! Приложение не должно быть подключено к XCode, потому что оно искажает обработку сигнала. – allprog

Смежные вопросы