it-swarm.com.ru

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

Я запускаю фоновую выборку, используя флаг content-available в Push-уведомлении. У меня включены fetch и remote-notificationUIBackgroundModes.

Вот реализация, которую я использую в своем 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) показывает это: enter image description here

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

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

Таким образом, реальный вопрос:

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

211
Santa Claus

UPDATE2:

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


UDPDATE1:

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

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


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

https://devforums.Apple.com/message/873265#873265 (требуется регистрация)

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

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

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

211
Santa Claus

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

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

screenshot

68
runmad

Ответ ДА, но не следует использовать "Фоновая выборка" или "Удаленное уведомление". 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 - я протестировал его на своем устройстве, и он работает как и ожидалось.

36
superZhen

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

enabling bg fetch

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

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

14
Danil

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

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

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

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

3
snarshad

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

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

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

2
Stanislav S.