IOS lancera-t-il mon application en arrière-plan si elle a été forcée de quitter l'utilisateur?

219

Je déclenche une extraction en arrière-plan en utilisant l' content-availableindicateur sur une notification push. J'ai le fetchet remote-notification UIBackgroundModesactivé.

Voici l'implémentation que j'utilise dans mon 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);

}

Lorsque l'application s'exécute en arrière-plan, cela fonctionne bien. (La notification est reçue et l'application a déclenché la notification locale "On dirait que j'ai reçu une notification", comme le code ci-dessus devrait le faire).

Toutefois, lorsque l'application n'est pas en cours d'exécution et qu'une notification push est reçue avec l' content-availableindicateur, l'application n'est pas lancée et la didRecieveRemoteNotificationméthode déléguée n'est jamais appelée.

La vidéo WWDC Quoi de neuf avec le multitâche (# 204 de WWDC 2013) montre ceci:entrez la description de l'image ici

Il indique que l'application est "lancée en arrière-plan" lorsqu'une notification push est reçue avec le content-availabledrapeau.

Pourquoi mon application ne se lance-t-elle pas en arrière-plan?

La vraie question est donc:

IOS effectuera-t-il des tâches en arrière-plan une fois que l'utilisateur aura forcé la fermeture de l'application?

père Noël
la source
Comment vérifiez-vous si l'application se lance en arrière-plan?
runmad
1
@ runun Je connecte un tas de merde- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Père Noël
Comment l'enregistrez-vous, juste NSLog? Vous devrez définir le lancement sur manuel dans les paramètres de votre programme d'application (voir la réponse)
runmad
@runmad voir le commentaire sur la réponse
Père Noël
@HaimBenchimol Djd vous obtenez une réponse à votre rapport de bug? Je n'ai pas réussi à déposer mon propre rapport de bogue.
Père Noël

Réponses:

215

MISE À JOUR2:

Vous pouvez y parvenir en utilisant le nouveau framework PushKit, introduit dans iOS 8. Bien que PushKit soit utilisé pour la VoIP. Votre utilisation devrait donc être liée à la VoIP, sinon il y a un risque de rejet de l'application. (Voir cette réponse ).


UDPDATE1:

La documentation a été clarifiée pour iOS8 . La documentation peut être lue ici . Voici un extrait pertinent:

Utilisez cette méthode pour traiter les notifications distantes entrantes pour votre application. Contrairement à la application:didReceiveRemoteNotification:méthode, qui est appelée uniquement lorsque votre application s'exécute au premier plan, le système appelle cette méthode lorsque votre application s'exécute au premier plan ou en arrière-plan. De plus, si vous avez activé le mode d'arrière-plan des notifications à distance, le système lance votre application (ou la sort de l'état suspendu) et la met en arrière-plan lorsqu'une notification push arrive. Cependant, le système ne lance pas automatiquement votre application si l'utilisateur l'a forcée à la quitter. Dans ce cas, l'utilisateur doit relancer votre application ou redémarrer l'appareil avant que le système ne tente de relancer automatiquement votre application.


Bien que cela n'ait pas été précisé par la vidéo de la WWDC, une recherche rapide sur les forums de développeurs a révélé ceci:

https://devforums.apple.com/message/873265#873265 (connexion requise)

Gardez également à l'esprit que si vous tuez votre application à partir du sélecteur d'application (c'est-à-dire en glissant vers le haut pour tuer l'application), le système d'exploitation ne relancera jamais l'application, quelle que soit la notification push ou la récupération en arrière-plan. Dans ce cas, l'utilisateur doit relancer manuellement l'application une fois, puis à partir de ce moment, les activités d'arrière-plan seront appelées. - pmarcos

Ce message a été rédigé par un employé d'Apple, je pense donc que je peux avoir confiance que ces informations sont correctes.

Il semble donc que lorsque l'application est supprimée du sélecteur d'application (en faisant glisser vers le haut), l'application ne sera jamais lancée, même pour les récupérations d'arrière-plan planifiées.

père Noël
la source
2
Pour moi, l'ajout de l'action dans "didFinishLaunchingWithOptions" lorsque les options de lancement ne sont pas nulles a fait le travail. J'ai la même méthode ici que dans "didreceiveRemoteNotification"
harsh.prasad
@ harsh.prasad c'est intéressant. Le problème était que l'application n'est pas lancée lorsqu'elle a été supprimée du sélecteur d'application.
Père Noël
3
L'application n'a pas besoin d'être affichée dans le sélecteur d'application si un push silencieux est reçu. Il pourrait être lancé en arrière-plan sans l'ajouter au sélecteur d'application, et être autorisé à s'exécuter et à "faire son travail", puis à quitter. Les applications qui restent actives trop longtemps seraient supprimées de la même manière qu'elles le sont déjà.
MindJuice
1
@chrizstone La solution est que c'est un comportement voulu, et vous ne pouvez rien y faire.
Père Noël
1
@JPK Euh, les notifications push elles-mêmes ne sont pas affectées. Il s'agit simplement d'effectuer des tâches d'arrière-plan qui ne fonctionneront pas après la fermeture forcée.
Père Noël
70

Vous pouvez modifier les paramètres de lancement de votre cible dans "Gérer le schéma" en Wait for <app>.app to be launched manually, ce qui vous permet de déboguer en définissant un point d'arrêt application: didReceiveRemoteNotification: fetchCompletionHandler:et en envoyant la notification push pour déclencher le lancement en arrière-plan.

Je ne suis pas sûr que cela résoudra le problème, mais cela peut vous aider pour le débogage pour l'instant.

capture d'écran

runmad
la source
donc cela a aidé mais le problème existe toujours
Père Noël
Étrange. Je suppose que vous avez plus que revérifié tous les flashs sont définis dans votre plist, etc.?
runmad
De plus, je sais que tout est bien réglé, car lorsque l'application est en arrière-plan, tout fonctionne parfaitement. C'est juste lorsque l'application ne fonctionne pas du tout qu'elle ne fonctionne pas.
Père Noël
Je me demande si un déclencheur de lancement de notification push est déterminé par le système. Par exemple, si iOS détermine que ce n'est pas le moment idéal pour lancer l'application, il peut la reporter à plus tard. Essayez peut-être de fermer toutes les applications en cours d'exécution / d'arrière-plan et de voir ce qui se passe? Je suis juste en train de deviner à ce stade: - /
runmad
juste essayé ça. Rien ne s'est passé, comme d'habitude. Je pourrais demander sur les forums de développement.
Père Noël
37

La réponse est OUI, mais ne doit pas utiliser «Récupération en arrière-plan» ou «Notification à distance». PushKit est la réponse que vous désirez.

En résumé, PushKit, le nouveau cadre d'ios 8, est le nouveau mécanisme de notification push qui peut lancer silencieusement votre application en arrière-plan sans invite d'alerte visuelle, même si votre application a été tuée en glissant du sélecteur d'application, étonnamment vous ne pouvez même pas la voir du sélecteur d'application.

Référence PushKit d'Apple:

Le framework PushKit fournit les classes pour que vos applications iOS reçoivent des push depuis des serveurs distants. Les push peuvent être de deux types: standard et VoIP. Les push standard peuvent fournir des notifications comme dans les versions précédentes d'iOS. Les push VoIP fournissent des fonctionnalités supplémentaires en plus du push standard requis pour les applications VoIP pour effectuer le traitement à la demande du push avant d'afficher une notification à l'utilisateur.

Pour déployer cette nouvelle fonctionnalité, veuillez vous référer à ce tutoriel: https://zeropush.com/guide/guide-to-pushkit-and-voip - Je l'ai testé sur mon appareil et il fonctionne comme prévu.

superZhen
la source
9
Il me semble que vous devez définir votre application comme utilisant la VoIP. Si votre application n'est pas réellement une application VoIP, ne sera-t-elle pas simplement rejetée lors de la révision?
duncanc4
6
Malheureusement, connaissant le processus de validation par Apple, il serait logique que la demande soit rejetée.
Kepa Santos
3
Utilisé pour VoIP. Si vous n'utilisez pas la VoIP pour l'utilisateur, cela augmentera considérablement le risque de rejet de la révision.
Chris
Il semble que les grands fournisseurs utilisent cette fonction comme excuse pour exécuter des choses en arrière-plan et Apple ferme les yeux. Devenir Android une fonctionnalité à la fois.
TCB13
PushKit est réservé à la VoIP, aux fournisseurs de fichiers et aux complications de surveillance. Il n'est pas disponible pour les cas d'utilisation décrits dans cette réponse.
quellish
15

En fait, si vous devez tester la récupération en arrière-plan, vous devez activer une option dans le schéma:

activation de la récupération de bg

Une autre façon de le tester: simuler bg fetch

Voici des informations complètes sur cette nouvelle fonctionnalité: http://www.objc.io/issue-5/multitasking.html

Danil
la source
4

J'essaie différentes variantes de cela depuis des jours, et j'ai pensé un jour que je l'avais relancé l'application en arrière-plan, même lorsque l'utilisateur a glissé pour tuer, mais non, je ne peux pas reproduire ce comportement.

Il est regrettable que le comportement soit assez différent qu'auparavant. Sur iOS 6, si vous supprimiez l'application des icônes tremblantes, elle serait toujours réactivée sur les déclencheurs SLC. Maintenant, si vous tuez en glissant, cela ne se produit pas.

C'est un comportement différent, et l'utilisateur, qui continuerait à obtenir des informations utiles de notre application s'il l'avait tué sur iOS 6, ne le fera plus.

Nous devons inciter nos utilisateurs à rouvrir l'application maintenant s'ils ont glissé pour la tuer et attendent toujours certains des comportements de notification que nous leur donnions. Je crains que cela ne soit pas évident pour les utilisateurs lorsqu'ils balaient une application. Ils peuvent, après tout, être en train de nettoyer ou de réorganiser les applications qui sont affichées minimisées.

snarshad
la source
2
C'est exactement ce que nous avons fait (applicationWillTerminate), mais je ne pense pas qu'il ait donné la notification lors des purges de mémoire, du moins pas sur iOS 7. J'ai remarqué qu'il montrait la notification juste avant un redémarrage pour une mise à niveau du système d'exploitation, mais c'est ainsi rare cela ne semblait pas trop mal.
snarshad
"Sur iOS 6, si vous supprimiez l'application des icônes tremblantes, elle se réveillerait toujours sur les déclencheurs SLC. Maintenant, si vous tuez en glissant, cela ne se produit pas." Cela se produit maintenant, c'était une régression temporaire dans une première version d'iOS 7.
funkybro
3

Cela pourrait vous aider

Dans la plupart des cas, le système ne relance pas les applications après leur fermeture forcée par l'utilisateur. Une exception est les applications de localisation, qui dans iOS 8 et versions ultérieures sont relancées après avoir été forcées de quitter par l'utilisateur. Dans d'autres cas, cependant, l'utilisateur doit lancer l'application explicitement ou redémarrer l'appareil avant que l'application puisse être lancée automatiquement en arrière-plan par le système. Lorsque la protection par mot de passe est activée sur l'appareil, le système ne lance pas d'application en arrière-plan avant que l'utilisateur ne déverrouille l'appareil pour la première fois.

Source: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Stanislav S.
la source
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 

Contexte POUSSES Le lien vidéo: https://developer.apple.com/videos/play/wwdc2019/707/

CrazyPro007
la source
Pouvez-vous me partager le lien vidéo s'il vous plaît?
guhan0