Ответ 1
CoreBluetooth
восстановление состояния применяется только к соединениям и периферийным событиям. Единственное, что полагается на сканирование, в настоящее время не поддерживается.
Я пытаюсь сделать базовое 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 в фоновом режиме.
Спасибо!
CoreBluetooth
восстановление состояния применяется только к соединениям и периферийным событиям. Единственное, что полагается на сканирование, в настоящее время не поддерживается.
Когда вы нажимаете кнопку "Дом", чтобы отправить приложение в фоновый режим, оно приостанавливается и может обрабатывать делегаты Bluetooth и работать в фоновом режиме в течение 10 секунд, эту функцию можно достичь исключительно "добавьте bluetooth в фоновом режиме в info.plist", и не использует государственное сохранение и восстановление.
Если ваше приложение завершено IOS, из-за нехватки памяти, он больше не может обрабатывать делегатов Bluetooth. В этом случае, если вы использовали State Preservation and Restoration, ваше приложение может быть перезапущено в фоновый режим для повторного запуска, а также всего за 10 секунд. Через 10 секунд он переместится в приостановленное состояние. Только в этой ситуации может запускаться CBCentralManager willRestoreState.
Вы можете добавить код
kill (getpid(), SIGKILL);
к действию кнопки, когда вы нажмете кнопку, ваше приложение будет завершено IOS, как убитое давлением памяти, а затем будет вызвано "willRestoreState".
Удачи.
У меня также есть эта проблема с фоновым сканированием для периферийных устройств с известной услугой UUIDs
. Возможно, это ошибка в iOS. Я обнаружил, что iOS перезапускает приложение, когда обнаруживает периферийное устройство, что можно увидеть, наблюдая за выходом консоли из диспетчера устройств в XCode. Вызывается делегат didFinishLaunchingWithOptions
, но вызов делегата CBCentralManager's
willRestoreState
задерживается до тех пор, пока пользователь вручную не выведет приложение на передний план.
Как будто цикл события в основном потоке не запускается, даже если приложение запущено. Например, при добавлении кода:
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Hello from the main thread");
});
для делегата didFinishLaunchingWithOptions
, сообщение не отображается в консоли отладки, пока приложение не переместится на передний план.
Моим обходным путем является использование отдельной очереди, выполняемой в отдельном потоке, вместо передачи queue:nil
при создании CBCentralManager
. Таким образом, делегаты вызываются, пока приложение все еще находится в фоновом режиме.