Чи запустить 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);

}

Коли програма працює у фоновому режимі, вона працює чудово. (Повідомлення отримано, і додаток викликає локальне сповіщення "схоже на те, що я отримав сповіщення", як це повинен робити код).

Однак, коли програма не працює та надходить поштове сповіщення із content-availableпрапором, додаток не запускається і didRecieveRemoteNotificationметод делегування ніколи не викликається.

Відео WWDC Що нового у багатозадачності (№204 від WWDC 2013) показує це:введіть тут опис зображення

У ньому йдеться про те, що додаток "запускається у фоновий режим", коли надходить натиснене повідомлення із content-availableпрапором.

Чому мій додаток не запускається на другий план?

Тож справжнє питання:

Чи буде iOS виконувати фонові завдання після того, як користувач примусить запустити додаток?


Як ви перевіряєте, чи запускається програма у фоновому режимі?
runmad

1
@runmad Я зареєстрував купу ганьби- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Дід Мороз

Як ви це реєструєте, просто NSLog? Вам потрібно буде встановити керівництво «Запуск» у налаштуваннях схеми додатків (див. Відповідь)
runmad

@runmad дивіться коментар до відповіді
Дід Мороз

@HaimBenchimol Djd Ви отримали відповідь на свій звіт про помилку? Я не збирався подавати власний звіт про помилку.
Дід Мороз

Відповіді:


215

ОНОВЛЕННЯ2:

Ви можете досягти цього, використовуючи нову рамку PushKit, представлену в iOS 8. Хоча PushKit використовується для VoIP. Таким чином, ваше використання повинно бути пов'язане з VoIP, інакше є ризик відхилення програми. (Дивіться цю відповідь ).


UDPDATE1:

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

Використовуйте цей метод для обробки вхідних віддалених сповіщень для вашої програми. На відміну від application:didReceiveRemoteNotification:методу, який викликається лише тоді, коли ваша програма працює на передньому плані, система викликає цей метод, коли ваш додаток працює на передньому плані або на задньому плані. Крім того, якщо ви ввімкнули фоновий режим віддаленого сповіщення, система запускає вашу програму (або вибудовує її з призупиненого стану) і переводить її у фоновий стан, коли надходить натиснене повідомлення. Однак система не запускає додаток автоматично, якщо користувач примушує його закрити. У цій ситуації користувач повинен перезапустити додаток або перезапустити пристрій, перш ніж система спробує запустити додаток автоматично.


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

https://devforums.apple.com/message/873265#873265 (обов'язковий вхід)

Також майте на увазі, що якщо ви вб'єте додаток із програми перемикача програм (тобто проведіть пальцем, щоб знищити додаток), ОС ніколи не перезапустить програму, незалежно від натискання сповіщення чи отримання фонового режиму. У цьому випадку користувачеві потрібно вручну перезапустити додаток один раз, а потім з цього моменту буде запущено фонові дії. - 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

Крім того, я знаю, що у мене все встановлено правильно, оскільки коли програма знаходиться у фоновому режимі, все працює чудово. Це просто тоді, коли програма зовсім не працює, що не працює.
Дід Мороз

Цікаво, чи визначається тригер запуску сповіщень. Наприклад, якщо iOS визначить, що зараз не чудовий час для запуску програми, він може відкласти її на потім. Можливо, спробуйте закрити всі запущені / фонові програми та побачити, що відбувається? Я просто здогадуюсь у цей момент: - /
runmad

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

37

Відповідь ТАК, але не слід використовувати "Вибір фонового зображення" або "Віддалене сповіщення". PushKit - відповідь, яку ви бажаєте.

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

Посилання PushKit від Apple:

Рамка PushKit забезпечує класи ваших додатків для iOS отримувати натиски з віддалених серверів. Натискання можуть бути одного з двох типів: стандартні та VoIP. Стандартні натискання можуть надсилати сповіщення так само, як і в попередніх версіях iOS. Натискання VoIP надають додаткову функціональність поверх стандартного натискання, необхідного VoIP-програмам, щоб виконати обробку натискання на вимогу, перш ніж показувати сповіщення користувачеві.

Щоб розгорнути цю нову функцію, зверніться до цього підручника: https://zeropush.com/guide/guide-to-pushkit-and-voip - я протестував її на своєму пристрої, і вона працює як слід.


9
Мені здається, ви повинні встановити свій додаток як VoIP. Якщо ваша програма насправді не є програмою VoIP, чи не буде вона просто відхилена під час перегляду?
duncanc4

6
На жаль, знаючи процес перевірки Apple, було б логічно, що заявку було відхилено.
Кепа Сантос

3
Використовується для VoIP. Якщо не використовувати VoIP для користувача, це значно збільшить ризик відхилення перевірки.
Кріс

Схоже, великі постачальники використовують цей інструмент як привід для запуску матеріалів у фоновому режимі, і Apple працює на очі. На той час Android стає однією функцією.
TCB13

PushKit зарезервований для VoIP, постачальників файлів і перегляду складностей. Це недоступно для випадків використання, в яких описана ця відповідь.
чудовий

15

Насправді, якщо вам потрібно протестувати фоновий вибір, потрібно включити один варіант схеми:

включення добору bg

Ще один спосіб тестування: імітувати bg fetch

Ось повна інформація про цю нову функцію: http://www.objc.io/issue-5/multitasking.html


4

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

Прикро, що поведінка зовсім інша, ніж раніше. На iOS 6, якщо ви вбили додаток із піктограм, що рухаються, він все одно знову прокинеться на триггерах SLC. Тепер, якщо ти вбиваєш пальцем, цього не станеться.

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

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


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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.