web-dev-qa-db-fra.com

iOS: faire fonctionner une application comme un service

Sous iOS, comment pourrais-je demander au système d'exploitation de maintenir mon application en marche même si elle n'est plus au premier plan?

Et beaucoup d'autres applications le font.

23
BahaiResearch.com

En gros, une application de type service ou une fonctionnalité n'existe pas dans iOS. Même les applications "en arrière-plan" (UIBackgroundMode) ne peuvent pas s'exécuter entièrement librement et sans restrictions, comme un service ou un démon, etc. sur d'autres systèmes d'exploitation.

Voici la situation concernant l'exécution en arrière-plan, les notifications, les minuteries, etc. 

1) Une application ne peut s'exécuter en arrière-plan que si:

a) il demande du temps supplémentaire à l'OS pour le faire. Ceci est fait en utilisant beginBackgroundTaskWithExpirationHandler. Apple ne précise pas (intentionnellement) la durée de ce délai supplémentaire, mais il est en pratique d’environ 10 minutes.

b) une application a un mode d’arrière-plan, les modes sont: voip, audio, location, newstand. Même si elle possède l'un de ces types, une application ne peut pas s'exécuter sans restrictions. Le reste de cette discussion suppose que l'application ne dispose pas d'un mode d'arrière-plan. Si vous essayez d'utiliser l'un de ces modes d'arrière-plan pour permettre à votre application de fonctionner en arrière-plan mais que votre application n'utilise pas de manière légitime les fonctionnalités spécifiques, votre application sera rejetée lors de la soumission du magasin d'applications (c'est-à-dire d'avoir un UIBackgroundMode il DOIT être soit: une application VoIP, LE BESOIN d’avoir des mises à jour continuelles de la position, la possibilité de lire de l’audio en arrière-plan en continu est une fonctionnalité fondamentale, ou bien une application de nouveau support).

2) Lorsqu'une application est suspendue, elle ne peut rien faire pour se réveiller directement. Il ne peut pas avoir préalablement programmé un NSTimer, il ne peut pas utiliser quelque chose comme performSelector: afterDelay. etc.

La SEULE façon dont l'application peut redevenir active est si l'UTILISATEUR fait quelque chose pour la rendre active. L'utilisateur peut le faire à partir des éléments suivants:

a) Lancez l'application directement depuis son icône

b) Lancez l'application en réponse à une notification locale préalablement programmée par l'application pendant qu'elle était active.

c) Lancez l'application en réponse à une notification à distance envoyée par un serveur.

d) Quelques autres: comme le lancement d'URL si l'application est enregistrée pour pouvoir être lancée via une URL; ou s'il est enregistré pour être capable de traiter un certain type de contenu.

Si une application est au premier plan lorsqu'une notification locale/distante est déclenchée, l'application la reçoit directement.

Si l'application n'est pas actuellement au premier plan lorsqu'une notification locale/distante est déclenchée, l'application ne la reçoit PAS. Aucun code n'est exécuté lorsque la notification est déclenchée!

Seulement si l'utilisateur sélectionne la notification, l'application deviendra active et pourra être exécutée.

Notez que l'utilisateur peut désactiver les notifications, soit pour l'ensemble du périphérique, soit pour une application spécifique, auquel cas il ne les verra jamais. Si le périphérique est éteint lorsqu'une notification est sur le point de se déclencher, il est perdu.

MISE À JOUR POUR IOS 7

1) il existe de nouveaux modes d’arrière-plan tels que la récupération d’arrière-plan (vous ne pouvez toujours pas être réveillé par le système d’exploitation de manière déterministe)

2) il y a maintenant une notification Push en arrière-plan

3) le temps de beginBackgroundTaskWithExpirationHandler a été réduit de 10 minutes à environ 3.

44
Gruntcakes

Les choses ont maintenant changé dans iOS7, c'est la version bêta maintenant.

Depuis le portail des développeurs Apple :

Maintenez le contenu de votre application à jour en adoptant le nouveau API multitâches dans iOS 7. Les nouveaux services permettent à votre application de mettre à jour informations et télécharger le contenu en arrière-plan sans drainer la batterie inutilement. Les mises à jour peuvent arriver à opportuniste fois et sont intelligemment planifiés en fonction de l'utilisation, de sorte que votre application pouvez mettre à jour le contenu en arrière-plan au moment où vos utilisateurs en ont besoin.

2
null

Oui on peut faire ça, 

Créez un champ privé pour suivre notre statut:

UIBackgroundTaskIdentifier _bgTask;

Appelez maintenant cette méthode pour exécuter votre application comme un service.

if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) 
{
   _bgTask = UIBackgroundTaskInvalid;
   [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(doBackground:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
}

Maintenant, créez un sélecteur

- (void) doBackground:(NSNotification *)aNotification
{
   UIApplication *app = [UIApplication sharedApplication];

   if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)])
   {
      _bgTask = [app beginBackgroundTaskWithExpirationHandler:^
      {
         dispatch_async(dispatch_get_main_queue(), ^
         {
            if (_bgTask != UIBackgroundTaskInvalid)
            {
               [app endBackgroundTask:_bgTask];
               _bgTask = UIBackgroundTaskInvalid;
            }
         });
      }];
   }
}

Lorsque vous avez terminé votre tâche, appelez le code ci-dessous.

UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(endBackgroundTask:)]) 
{
   if (_bgTask != UIBackgroundTaskInvalid)
   {
      [app endBackgroundTask:_bgTask];
      _bgTask = UIBackgroundTaskInvalid;
   }
}
0
Zoeb S