web-dev-qa-db-fra.com

code d'exécution iOS une fois par jour

L'idée derrière cette application est très simple: télécharger un fichier. Cependant, cette application sera destinée aux personnes qui ne se trouvent pas toujours dans la zone d'accès Internet. J'ai donc besoin de savoir qu'à, par exemple, à 9h00, le téléchargement d'un fichier sur le disque dur. Il y aura également un bouton dans l'application pour le faire manuellement, mais je le fais déjà.

Si j'ai bien compris, ce sera difficile si c'est même possible. Je sais qu'iOS n'aime pas le multitâche, mais je suis également conscient du fait qu'il permet des fonctions de minuterie en arrière-plan. Je suis ouvert à toutes les suggestions que quiconque pourrait faire pour y parvenir, même si cela implique d'écrire une application séparée. Merci.

Edit: Je vois qu’il est possible de travailler avec des notifications, voire avec le calendrier. Les idées de cette catégorie sont également les bienvenues.

Edit 2: J'ai aussi lu quelque chose sur un serveur externe en train de lancer une application, mais cela ne donnait aucune description.

23
Marcel Marino

Voici la situation en ce qui concerne l'exécution en arrière-plan, les notifications, les minuteries, etc., par rapport à une application programmant une activité périodique.

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

    1. 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 elle est en pratique d’environ 10 minutes.

    2. Une application a un mode d’arrière-plan, les modes sont: voip, audio, emplacement, kiosque. Même si elle possède l'un de ces types, une application ne peut pas s'exécuter sans certaines restrictions. Le reste de cette discussion suppose que l'application ne dispose pas d'un mode d'arrière-plan.

  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 utiliser quelque chose comme performSelector: afterDelay. etc.

    La SEULE manière 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:

    1. Lancer l'application directement depuis son icône

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

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

    4. Quelques autres: comme le lancement d'URL si l'application est enregistrée pour pouvoir être lancée via une URL; ou si son enregistrement est 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.

27
Gruntcakes

Vous pouvez utiliser les notifications locales. Ils exécutent le code lorsque l'utilisateur ouvre la notification présentée. Vous pouvez configurer la notification locale pour qu'elle se reproduise à un intervalle spécifié (par exemple, quotidiennement, toutes les heures, toutes les semaines, etc.). Cela nécessite toujours que l'utilisateur ouvre l'application pour lancer le processus.

Référence de classe UILocalNotification

Une fois la méthode déléguée activée, vous ne disposez que de quelques secondes pour exécuter le code. Inscrivez-vous pour une tâche d'arrière-plan longue et téléchargez ce que vous devez faire. S'il n'arrive pas à terminer le téléchargement dans les 10 minutes que vous avez pour la tâche, vous devez repenser votre stratégie de téléchargement.

Apple multitâche et arrière-plan

Nous utilisons ce même concept sur les applications iOS où je travaille. Cela fonctionnera donc si vous le configurez correctement.

UPDATE

Pour ceux qui sont curieux de savoir comment cela fonctionnera, il vous suffit d'implémenter les méthodes de délégation UILocalNotification. Ils héritent de UIApplicationDelegate qui devrait déjà être en place.

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// start your long running bg task here and update your file

}

** MISE À JOUR 2 **

La réponse de Martin H est la plus correcte à ce jour. Mais cela pose la question, si l'utilisateur n'ouvre jamais l'application, à quoi sert-il de télécharger des données qu'il ne verra jamais? Une notification locale récurrente leur rappelant d'ouvrir l'application et de la mettre à jour est peut-être la meilleure solution, mais oblige néanmoins l'utilisateur à interagir avec votre application s'il souhaite que celle-ci reste à jour et à jour.

1
Bill Burgess

Je suis à peu près sûr que ce n'est pas possible. Au mieux, vous pouvez envoyer des notifications Push à l'utilisateur, afin qu'elles se mettent à jour manuellement, le cas échéant.

1
Oscar Gomez

Les applications en arrière-plan ont une limite de temps définie (je crois 10 minutes, mais ne me citez pas dessus, cela pourrait être moins long) pour compléter ce sur quoi elles travaillent. Vous ne pourrez pas utiliser les tâches en arrière-plan pour faire ce que vous voulez.

Ce que vous pouvez faire est de définir un NSUserDefault avec la date du dernier téléchargement. Au lancement, vérifiez la date enregistrée. Si la date n’est pas la date du jour et qu’elle se situe après 9h00, lancez le téléchargement par programme.

0
Jeremy1026