2 votes

Gestion de la fermeture de l'application pendant la population de données de base de données en arrière-plan

J'ai regardé les réponses aux questions concernant l'exécution des sauvegardes de données de base en arrière-plan, mais aucune des réponses que j'ai trouvées n'a directement abordé le scénario suivant :

J'ai configuré les données de base de telle sorte que lorsque mon application est lancée pour la première fois, les données de base sont peuplées à partir d'un fichier plist, puis enregistrées dans le magasin persistant (tout cela sur un thread arrière-plan). Pendant ce temps, l'application affiche une fenêtre contextuelle "veuillez patienter" avec un indicateur d'activité animé. Cela semble bien fonctionner et en général l'application terminera le peuplement même si l'utilisateur appuie sur le bouton d'accueil pendant le peuplement, poussant l'application en arrière-plan. Cependant, il est possible que l'application puisse être complètement terminée avant que ce peuplement se termine (j'ai réussi à le faire en appuyant sur le bouton d'accueil, en double-cliquant sur le bouton d'accueil, et en supprimant l'application du bac multi-tâches très rapidement). Dans ce scénario, l'application se ferme sans enregistrer les données dans le magasin. Lors du prochain lancement de l'application, l'application reconnaît que le magasin existe déjà, donc elle ne se peuple pas, laissant ainsi l'utilisateur avec une base de données complètement vide. Alors la ou les question(s) est/sont :

  • Y a-t-il un moyen de supprimer complètement le magasin à la fermeture de l'application si le peuplement n'est pas terminé? J'ai essayé de le faire dans -applicationWillTerminate: ce qui ne semblait pas reconnaître correctement si l'application était en train de se peupler.

  • Ou, y a-t-il un meilleur moyen de reconnaître quand le magasin nécessite un peuplement ? Par exemple, puis-je déterminer si le magasin est vide au démarrage ?

2voto

sergio Points 52422

Je suggérerais cette approche générale pour votre problème:

  1. à la fin de la phase de population, écrivez un indicateur dans votre base de données principale ou dans vos préférences d'application (NSUserDefaults);

  2. (maintenant, si l'application est terminée avant la fin de la phase de population, l'indicateur ne sera pas enregistré);

  3. au démarrage, vérifiez cet indicateur; s'il est présent, vous saurez que la phase de population est terminée, sinon vous saurez que quelque chose s'est mal passé.

Évidemment, il y a une petite chance que l'application soit arrêtée juste après la fin de la phase de population et avant que l'indicateur ne soit enregistré; malgré que cet événement soit assez improbable, dans tous les cas, si cela se produisait, votre application devrait simplement peupler les données une fois de plus au prochain lancement, sans engendrer de problème de cohérence des données.

Une approche plus spécifique repose sur l'utilisation de beginBackgroundTaskWithExpirationHandler:

La méthode applicationDidEnterBackground: de votre délégué d'application a approximativement 5 secondes pour terminer toutes les tâches et retourner. En pratique, cette méthode devrait retourner aussi rapidement que possible. Si la méthode ne retourne pas avant la fin du temps imparti, votre application est tuée et supprimée de la mémoire. Si vous avez besoin de plus de temps pour effectuer des tâches, appelez la méthode beginBackgroundTaskWithExpirationHandler: pour demander du temps d'exécution en arrière-plan, puis lancez toutes les tâches de longue durée dans un fil secondaire. Peu importe que vous ayez démarré des tâches en arrière-plan, la méthode applicationDidEnterBackground: doit tout de même se terminer dans les 5 secondes.

Cela vous permettra d'avoir plus de temps pour terminer la phase de population avant que l'application ne soit arrêtée dans tout cas "non-pathologique" (c'est-à-dire que cela ne fonctionnera pas si l'utilisateur ferme l'application comme vous l'avez fait dans votre test, et ne sera pas sûr en cas de problème interne de l'application et de crash pendant que le thread en arrière-plan effectue la population).

J'espère que cela vous aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X