Будет ли iOS запускать мое приложение в фоновом режиме, если оно было принудительно завершено пользователем?

219

Я запускаю фоновую загрузку, используя content-availableфлаг в push-уведомлении. У меня есть fetchи remote-notification UIBackgroundModesвключен.

Вот реализация, которую я использую в своем AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification Recieved");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody =  @"Looks like i got a notification - fetch thingy";
    [application presentLocalNotificationNow:notification];
    completionHandler(UIBackgroundFetchResultNewData);

}

Когда приложение работает в фоновом режиме, оно работает нормально. (Уведомление получено, и приложение запустило локальное уведомление «похоже, я получил уведомление», как и приведенный выше код).

Однако, когда приложение не запущено и получено push-уведомление с content-availableфлагом, приложение не запускается и didRecieveRemoteNotificationметод делегата никогда не вызывается.

Видео WWDC Что нового с многозадачностью (# 204 от WWDC 2013) показывает это:введите описание изображения здесь

В нем говорится, что приложение «запускается в фоновом режиме» при получении push-уведомления с content-availableфлагом.

Почему мое приложение не запускается в фоновом режиме?

Итак, настоящий вопрос:

Будет ли iOS выполнять фоновые задачи после принудительного выхода из приложения?

Дед Мороз
источник
Как вы проверяете, запускается ли приложение в фоновом режиме?
runmad
1
@runmad Я записываю кучу дерьма- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Дед Мороз
Как вы это регистрируете, просто NSLog? Вам нужно будет настроить Launch на manual в настройках схемы вашего приложения (см. Ответ)
runmad
@runmad см. комментарий к ответу
Дед Мороз
@HaimBenchimol Djd вы получили ответ на сообщение об ошибке? Я не удосужился подать свой собственный отчет об ошибке.
Дед Мороз

Ответы:

215

UPDATE2:

Вы можете добиться этого, используя новую платформу PushKit, представленную в iOS 8. Хотя PushKit используется для VoIP. Таким образом, ваше использование должно быть связано с VoIP, в противном случае существует риск отклонения приложения. (См. Этот ответ ).


UDPDATE1:

Документация была уточнена для iOS8 . Документацию можно прочитать здесь . Вот соответствующая выдержка:

Используйте этот метод для обработки входящих удаленных уведомлений для вашего приложения. В отличие от application:didReceiveRemoteNotification:метода, который вызывается только тогда, когда ваше приложение работает на переднем плане, система вызывает этот метод, когда ваше приложение работает на переднем плане или в фоновом режиме. Кроме того, если вы включили фоновый режим удаленных уведомлений, система запускает ваше приложение (или выводит его из приостановленного состояния) и переводит его в фоновое состояние при получении push-уведомления. Однако система не запускает ваше приложение автоматически, если пользователь принудительно завершил его. В этой ситуации пользователь должен перезапустить ваше приложение или перезапустить устройство, прежде чем система попытается снова запустить ваше приложение автоматически.


Хотя это не было ясно из видео WWDC, быстрый поиск на форумах разработчиков показал это:

https://devforums.apple.com/message/873265#873265 (требуется вход в систему)

Также имейте в виду, что если вы убьете свое приложение из переключателя приложений (т. Е. Проведете пальцем вверх, чтобы убить приложение), то ОС никогда не перезапустит приложение, независимо от push-уведомления или фоновой выборки. В этом случае пользователь должен один раз вручную перезапустить приложение, а затем с этого момента будут вызываться фоновые действия. - pmarcos

Этот пост был написан сотрудником Apple, поэтому я думаю, что могу доверять этой информации.

Таким образом, похоже, что когда приложение убито из переключателя приложений (проведением пальцем вверх), приложение никогда не будет запущено, даже для запланированных фоновых загрузок.

Дед Мороз
источник
2
Для меня добавление действия в "didFinishLaunchingWithOptions", когда параметры запуска не равны нулю, сделало работу. У меня здесь тот же метод, что и в "didreceiveRemoteNotification"
harsh.prasad
@ harsh.prasad это интересно. Проблема заключалась в том, что приложение не запускалось, когда оно было убито из переключателя приложений.
Дед Мороз
3
Приложение не должно отображаться в переключателе приложений, если получено тихое нажатие. Он может быть запущен в фоновом режиме, не добавляя его в переключатель приложений, и может быть запущен, «делать свое дело» и затем завершиться. Приложения, которые остаются активными слишком долго, будут уничтожены так же, как они уже.
MindJuice
1
@chrizstone Решение заключается в том, что это предполагаемое поведение, и вы ничего не можете с этим поделать.
Дед Мороз
1
@JPK Ну, сами уведомления не затрагиваются. Он просто выполняет фоновые задачи, которые не будут работать после принудительного выхода.
Дед Мороз
70

Вы можете изменить настройки запуска вашей цели в «Управление схемой» на Wait for <app>.app to be launched manually, что позволяет отлаживать ее, устанавливая точку останова application: didReceiveRemoteNotification: fetchCompletionHandler:и отправляя push-уведомление для запуска фонового запуска.

Я не уверен, что это решит проблему, но пока может помочь с отладкой.

Скриншот

runmad
источник
так что это помогло, но проблема все еще существует
Дед Мороз
Странный. Я предполагаю, что вы более чем дважды проверили, все ли вспышки установлены в вашем списке и т. Д.?
Runmad
Кроме того, я знаю, что у меня все настроено правильно, потому что, когда приложение находится в фоновом режиме, все работает отлично. Это просто, когда приложение не работает вообще, что это не так.
Дед Мороз
Интересно, является ли запуск-запуск push-уведомлений системным. Например, если iOS определит, что сейчас не самое подходящее время для запуска приложения, оно может отложить его на потом. Возможно, попробуйте закрыть все запущенные / фоновые приложения и посмотреть, что произойдет? Я просто догадываюсь на этом этапе: - /
runmad
только что попробовал. Ничего не произошло, как обычно. Я мог бы спросить на форумах разработчиков.
Дед Мороз
37

Ответ ДА, но не следует использовать «Фоновая выборка» или «Удаленное уведомление». PushKit - это ответ, который вы желаете.

Таким образом, PushKit, новая платформа в ios 8, представляет собой новый механизм push-уведомлений, который может автоматически запускать ваше приложение в фоновом режиме без визуального оповещения, даже если ваше приложение было убито, если его убрать из переключателя приложений, удивительно, что вы даже не видите его из переключателя приложений.

Ссылка PushKit от Apple:

Платформа PushKit предоставляет классы для ваших приложений iOS, чтобы получать нажатия от удаленных серверов. Толчки могут быть одного из двух типов: стандартные и VoIP. Стандартные нажатия могут доставлять уведомления так же, как в предыдущих версиях iOS. Push-сигналы VoIP предоставляют дополнительные функциональные возможности в дополнение к стандартному push-запросу, который необходим приложениям VoIP для выполнения обработки push-уведомлений перед отображением уведомления пользователю.

Чтобы развернуть эту новую функцию, обратитесь к этому руководству: https://zeropush.com/guide/guide-to-pushkit-and-voip - я протестировал его на своем устройстве, и он работает, как и ожидалось.

superZhen
источник
9
Похоже, вы должны настроить приложение на использование VoIP. Если ваше приложение на самом деле не является приложением VoIP, не будет ли оно отклонено во время проверки?
duncanc4
6
К сожалению, зная процесс проверки Apple, было бы логично, что приложение было отклонено.
Кепа Сантос
3
Используется для VoIP. Если не использовать VoIP для пользователя, это значительно увеличит риск отклонения отзыва.
Крис
Похоже, что крупные провайдеры используют эту возможность в качестве предлога для запуска вещей в фоновом режиме, и Apple закрывает глаза. Стать Android одной функцией в то время.
TCB13
PushKit зарезервирован для VoIP, провайдеров файлов и усложнения просмотра. Этот вариант недоступен для вариантов использования, описанных в этом ответе.
скверный
15

На самом деле, если вам нужно протестировать фоновую выборку, вам нужно включить одну опцию в схеме:

включение bg fetch

Другой способ, как вы можете проверить это: симулировать bg fetch

Вот полная информация об этой новой функции: http://www.objc.io/issue-5/multitasking.html

Данил
источник
4

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

К сожалению, поведение совсем другое, чем раньше. На iOS 6, если вы убьете приложение из-за движущихся значков, оно все равно будет повторно активировано при срабатывании SLC. Теперь, если вы убиваете, проводя, это не произойдет.

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

Мы должны подтолкнуть наших пользователей к повторному открытию приложения сейчас, если они сделали это, чтобы убить его, и все еще ожидают некоторые из уведомлений, которые мы использовали для их предоставления. Я беспокоюсь, что это не будет очевидно для пользователей, когда они удаляют приложение. Они могут, в конце концов, в основном убирать или хотеть изменить расположение приложений, которые показаны свернутыми.

snarshad
источник
2
Это именно то, что мы сделали (applicationWillTerminate), но я не верю, что оно давало уведомление во время очистки памяти, по крайней мере, на iOS 7. Я заметил, что оно показывало уведомление прямо перед перезагрузкой для обновления ОС, но это так редко это не казалось слишком плохим.
snarshad
«В iOS 6, если вы убили приложение из-за движущихся значков, оно все равно было бы повторно активировано при срабатывании SLC. Теперь, если вы убьете с помощью смахивания, этого не произойдет». Это теперь происходит, это была временная регрессия в ранней версии iOS 7.
funkybro
3

Это может помочь вам

В большинстве случаев система не перезапускает приложения после их принудительного выхода пользователем. Единственным исключением являются приложения определения местоположения, которые в iOS 8 и более поздних версиях перезапускаются после принудительного выхода пользователем. Однако в других случаях пользователь должен явно запустить приложение или перезагрузить устройство, прежде чем система сможет автоматически запустить приложение в фоновом режиме. Если на устройстве включена защита паролем, система не запускает приложение в фоновом режиме до того, как пользователь впервые разблокирует устройство.

Источник: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Станислав С.
источник
3
For **iOS13**

For background PUSHES in iOS13 you must set below parameters
apns-priority = 5
apns-push-type = background
Required for WatchOS
Highly recommended for Other platforms 

Фоновые толчки Ссылка на видео: https://developer.apple.com/videos/play/wwdc2019/707/

CrazyPro007
источник
Не могли бы вы поделиться ссылкой на видео, пожалуйста?
guhan0