Background Task est un mécanisme iOS qui permet à une application de terminer une opération après être passée en arrière-plan. Le système alloue un temps limité (jusqu'à 30 secondes) pour exécuter la tâche, après quoi l'application est suspendue de force. Selon Apple, 2026, l'utilisation d'un gestionnaire d'expiration est une exigence obligatoire pour terminer correctement une tâche en arrière-plan.
Points clés
Background Task est un mécanisme programmable iOS qui permet à une application de prolonger le temps d'exécution après être passée en arrière-plan. Lorsque l'utilisateur minimise l'application, le système appelle UIApplicationDelegate.applicationDidEnterBackground. Si une opération critique est en cours à ce moment-là (sauvegarde de données, envoi d'une requête), l'application peut demander du temps supplémentaire via beginBackgroundTask.
Sans utiliser Background Task, l'application est suspendue de force dans les 3–5 secondes après le passage en arrière-plan. Toutes les opérations incomplètes sont interrompues : les données ne sont pas sauvegardées, les requêtes réseau sont abandonnées, les états sont perdus. Background Task donne à l'application jusqu'à 30 secondes pour terminer correctement ces opérations.
beginBackgroundTask est apparu dans iOS 4.0 — la première version prenant en charge le multitâche. Avant iOS 4, l'application était complètement arrêtée en appuyant sur le bouton Accueil. iOS 7 a introduit Background Fetch et la configuration en arrière-plan d'URLSession. À partir d'iOS 13, Apple recommande BGTaskScheduler pour les nouveaux projets, mais beginBackgroundTask reste pertinent pour les opérations à court terme.
beginBackgroundTask est une méthode d'UIApplication qui enregistre une tâche et retourne un identifiant unique UIBackgroundTaskIdentifier. Le système augmente le minuteur d'exécution en arrière-plan. Lorsque le temps expire, le gestionnaire d'expiration est appelé, après quoi l'application doit appeler endBackgroundTask(identifier:) pour terminer correctement la tâche.
Étape 1 — l'application reçoit la notification didEnterBackground. Étape 2 — beginBackgroundTask(expirationHandler:) est appelé. Étape 3 — l'opération critique (sauvegarde, requête réseau) est exécutée. Étape 4 — une fois terminée, endBackgroundTask(identifier:) est appelé. Si l'opération ne se termine pas en 30 secondes — le système appelle le gestionnaire d'expiration, et l'application doit terminer la tâche immédiatement.
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Gestionnaire d'expiration
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
func finishBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
La propriété backgroundTimeRemaining retourne le nombre de secondes restantes avant que la tâche en arrière-plan ne soit terminée de force. La valeur diminue en temps réel. Si l'application n'est pas en arrière-plan — elle retourne DBL_MAX. Utilisez cette propriété pour adapter le comportement : lorsqu'il reste moins de 5 secondes, interrompez les opérations longues et sauvegardez la progression.
Une application peut enregistrer plusieurs Background Tasks simultanément. Chaque tâche reçoit son propre identifiant. Le temps d'exécution total est cumulatif — si 3 tâches sont enregistrées, l'application peut obtenir jusqu'à 90 secondes. Cependant, le système peut terminer l'application plus tôt si les ressources sont épuisées ou si la limite de batterie est dépassée.
Gestionnaire d'expiration est un bloc de code que le système appelle lorsque le temps alloué à la tâche en arrière-plan expire. Avoir un gestionnaire d'expiration est une exigence obligatoire d'Apple. Sans lui, l'application peut être terminée de force par le système et les données peuvent être perdues.
Le gestionnaire d'expiration doit effectuer des actions minimales pour sauvegarder l'état de l'application : sauvegarder les données actuelles dans un stockage persistant, appeler endBackgroundTask avec l'identifiant correspondant et définir l'identifiant sur .invalid. À l'intérieur du gestionnaire d'expiration, il est interdit de lancer de nouvelles opérations longues — le temps d'exécution est limité à 1–2 secondes.
func handleExpiration() {
// Sauvegarde de la progression d'exécution
saveProgressToUserDefaults()
// Annulation des requêtes réseau actives
currentTask?.cancel()
// Fin de Background Task
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Enregistrement avec gestionnaire d'expiration
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
withName: "SaveDocument",
expirationHandler: handleExpiration
)
L'erreur la plus courante est de ne pas appeler endBackgroundTask à l'intérieur du gestionnaire d'expiration. Dans ce cas, le système continue de considérer la tâche comme active, l'application ne passe pas à l'état suspendu et la batterie se décharge. La deuxième erreur est de lancer des opérations longues à l'intérieur du gestionnaire d'expiration. Le système peut terminer l'application avant leur achèvement et les données seront perdues.
Dans le gestionnaire d'expiration, le temps d'exécution est extrêmement limité — généralement moins d'une seconde. Par conséquent, à l'intérieur du gestionnaire, vous ne pouvez pas effectuer : des calculs complexes, des requêtes réseau, l'écriture de grandes quantités de données dans CoreData. Seulement des opérations atomiques : écrire une clé unique dans UserDefaults, définir un indicateur d'état, appeler endBackgroundTask.
Examinons une implémentation complète de Background Task pour sauvegarder un document lorsque l'application passe en arrière-plan. L'exemple inclut l'enregistrement de la tâche, l'exécution de l'opération avec vérification du temps restant et la terminaison correcte via endBackgroundTask.
En passant en arrière-plan, l'application initie la sauvegarde d'un grand document. Background Task fournit jusqu'à 30 secondes pour l'opération. Si le temps expire — le gestionnaire d'expiration sauvegarde les résultats intermédiaires. Une fois la sauvegarde terminée, endBackgroundTask est appelé pour libérer les ressources.
class DocumentManager {
private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func saveDocumentInBackground(document: Document) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
self.saveProgress(document)
self.endBackgroundTask()
}
DispatchQueue.global().async {
document.save()
self.endBackgroundTask()
}
}
private func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
Les requêtes réseau en arrière-plan nécessitent une attention particulière — le gestionnaire d'expiration peut interrompre la requête avant de recevoir une réponse. Utilisez URLSession avec dataTask et vérifiez backgroundTimeRemaining avant d'envoyer. S'il reste moins de 5 secondes — reportez l'envoi jusqu'au prochain réveil de l'application.
func sendCriticalData(data: Data) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Sauvegarde des données pour renvoi
saveForRetry(data)
self.endBackgroundTask()
}
let task = URLSession.shared.dataTask(with: request) { _, _, error in
if error != nil {
saveForRetry(data)
}
self.endBackgroundTask()
}
task.resume()
}
Pour les opérations longues, surveillez UIApplication.shared.backgroundTimeRemaining. Si la valeur tombe en dessous d'un seuil (10 secondes), interrompez l'opération en cours et commencez à sauvegarder les résultats intermédiaires. Cela permet une terminaison correcte avant que le gestionnaire d'expiration ne soit appelé de force.
Background Task est un mécanisme puissant, mais son utilisation inappropriée entraîne des problèmes de batterie et de performances. Suivre les recommandations d'Apple et les pratiques éprouvées de la communauté aidera à éviter les erreurs courantes et à garantir un fonctionnement stable de l'application.
Terminez la Background Task aussi rapidement que possible. Chaque seconde d'exécution en arrière-plan consomme de la batterie. Temps optimal — moins de 5 secondes. Si l'opération prend plus de temps — envisagez d'utiliser BGTaskScheduler ou Background Modes. Ne prolongez pas artificiellement la tâche via des appels beginBackgroundTask sans réel besoin.
Stockez UIBackgroundTaskIdentifier comme propriété d'une classe ou d'une structure. Ne le passez jamais comme variable globale — cela entraîne des conflits avec des tâches multiples. Définissez l'identifiant sur .invalid après avoir appelé endBackgroundTask pour éviter une double terminaison.
Dans le Simulateur Xcode, passez l'application en arrière-plan via le bouton Accueil (Command + Shift + H). Utilisez Debug — Simulate Background Fetch pour tester le réveil en arrière-plan. Pour simuler l'expiration du temps, définissez la variable d'environnement BACKGROUND_TASK_SIMULATE_EXPIRATION = YES — le gestionnaire d'expiration sera appelé dans les 5 secondes.
// Vérification du temps restant avant de commencer l'opération
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
// Temps insuffisant — reporter la tâche
scheduleForNextLaunch()
return
}
// Exécution de l'opération avec contrôle du temps
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
saveProgress()
self.endBackgroundTask()
}
Le gestionnaire d'expiration capture self — cela peut créer un cycle de rétention si backgroundTaskID est stocké comme propriété du même objet. Utilisez [weak self] dans la fermeture ou stockez l'identifiant séparément. Un cycle de rétention entraîne une fuite de mémoire — l'objet ne sera pas libéré tant que l'application ne se termine pas.
Avec la sortie d'iOS 13, Apple a présenté BGTaskScheduler — un remplacement moderne pour l'ancienne API Background Task. Les deux mécanismes résolvent des tâches similaires, mais BGTaskScheduler offre plus de contrôle et de flexibilité. Comprendre les différences aidera à choisir l'outil approprié pour un scénario spécifique.
| Caractéristique | Background Task | BGTaskScheduler |
|---|---|---|
| Version iOS | 4.0+ | 13.0+ |
| Temps max | 30 secondes | 30 s / 10 min (processing) |
| Initiation | didEnterBackground | Planification + système |
| Garantie d'exécution | Uniquement lors du passage en arrière-plan | À tout moment convenable pour le système |
| Gestionnaire d'expiration | Oui, obligatoire | Oui, via task.expirationHandler |
| Internet | Requis au démarrage | Disponible via requiresNetworkConnectivity |
| Charge | Non requise | Optionnelle pour processing |
beginBackgroundTask convient aux opérations à court terme qui doivent être exécutées immédiatement lors du passage en arrière-plan : sauvegarde d'état, achèvement d'une requête réseau, mise en cache de données. L'API est simple et ne nécessite pas de configuration Info.plist ni d'enregistrement d'identifiants. Idéal pour les opérations qui prennent moins de 10 secondes.
BGTaskScheduler convient aux tâches qui peuvent être exécutées à tout moment opportun : synchronisation périodique, nettoyage du cache, mise à jour des widgets. Le système lui-même sélectionne le moment optimal en tenant compte du comportement de l'utilisateur et de l'état de la batterie. Pour les opérations longues (jusqu'à 10 minutes), utilisez BGProcessingTask.
Les deux API peuvent être utilisées dans la même application. Background Task — pour les opérations immédiates lors du passage en arrière-plan (sauvegarde d'un brouillon). BGTaskScheduler — pour les mises à jour planifiées (synchronisation toutes les 6 heures). La séparation des responsabilités garantit une préservation correcte des données et une maintenance en arrière-plan économe en énergie.
Questions fréquentes
Oui, beginBackgroundTask peut être appelé à tout moment de l'exécution de l'application. Cependant, l'allocation de temps système ne commencera qu'après le passage en arrière-plan. Si l'application est au premier plan, appeler beginBackgroundTask n'a aucun effet — backgroundTimeRemaining retourne DBL_MAX, et la tâche sera activée lors du passage en arrière-plan.
Si endBackgroundTask n'est pas appelé, le système continue de considérer l'application comme active en arrière-plan. Après 30 secondes, le gestionnaire d'expiration sera appelé, mais s'il manque également endBackgroundTask — l'application reste en mémoire, déchargeant la batterie. Dans iOS 13+, le système termine de force une telle application après 3 minutes.
Le temps standard est de 30 secondes. Il ne peut être prolongé que via Background Modes : Audio (lecture), Localisation (géolocalisation), Bluetooth (BLE). Ou via BGProcessingTask (iOS 13+) — jusqu'à 10 minutes avec charge et Wi-Fi. beginBackgroundTask lui-même ne fournit pas de moyen d'augmenter la limite.
Oui, iPadOS prend entièrement en charge beginBackgroundTask avec les mêmes limitations que iOS. Sur iPad avec Stage Manager, l'application peut rester plus longtemps en mémoire — le système suspend les applications moins fréquemment en raison d'une RAM plus importante. Mais la limite de 30 secondes pour les tâches en arrière-plan demeure.
Connectez l'appareil à Xcode, lancez l'application, minimisez-la — les journaux système apparaîtront dans la console. Utilisez sysdiagnose pour collecter des journaux détaillés : déclenchez de force sysdiagnose depuis l'appareil (Volume Haut + Volume Bas + Alimentation). Dans le navigateur de débogage Xcode, surveillez l'activité des tâches en arrière-plan.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi