Comment créer un délai en Swift : 5 méthodes éprouvées

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

« Attends une seconde » : pourquoi les délais en Swift sont de la magie, pas des astuces

\n\n

Imaginez : vous développez une application de commande de pizza. L'utilisateur appuie sur « Payer », et instantanément — boum ! — le débit de l'argent. Sans animation, sans pause, sans sensation que « quelque chose se passe ». L'utilisateur a peur, ferme l'application, et vous perdez un client. Le délai en Swift n'est pas une béquille, mais un outil de conception UX et d'architecture correcte.

\n\n

La question « How to create a delay in Swift? » sur Stack Overflow a rassemblé des dizaines de milliers de vues. Et ce n'est pas surprenant : les débutants essaient d'utiliser sleep() (spoiler : ce n'est pas possible), tandis que les professionnels recherchent des solutions élégantes. Nous allons analyser 5 méthodes fonctionnelles — du classique GCD aux modernes async/await. C'est parti !

\n\n

1. Classique : DispatchQueue.main.asyncAfter (iOS 4+)

\n

La méthode la plus populaire pour créer un délai en Swift est DispatchQueue.main.asyncAfter. Elle fonctionne sur toutes les versions d'iOS et ne nécessite pas d'imports supplémentaires. Elle est adaptée pour exécuter du code sur le thread principal (par exemple, mise à jour de l'interface utilisateur).

\n\n
import UIKit\n\nclass ViewController: UIViewController {\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // Délai de 2 secondes\n        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n            print("2 secondes se sont écoulées !")\n            self.showAlert()\n        }\n    }\n    \n    func showAlert() {\n        let alert = UIAlertController(title: "Bonjour !", message: "C'est un délai", preferredStyle: .alert)\n        alert.addAction(UIAlertAction(title: "OK", style: .default))\n        present(alert, animated: true)\n    }\n}
\n\n

Avantages et inconvénients

\n
    \n
  • Avantages : simplicité, rétrocompatibilité, fonctionne sur le thread principal.
  • \n
  • Inconvénients : impossible d'annuler le délai (sauf si vous conservez un DispatchWorkItem).
  • \n
\n\n

2. Délai annulable via DispatchWorkItem

\n

Parfois, il est nécessaire d'annuler un délai — par exemple, si l'utilisateur quitte l'écran. DispatchWorkItem résout ce problème. On conserve une référence au « travail » et on appelle cancel().

\n\n
class DelayedTask {\n    private var workItem: DispatchWorkItem?\n    \n    func scheduleDelayedAction() {\n        // Créer la tâche\n        let item = DispatchWorkItem { [weak self] in\n            print("Tâche exécutée après le délai")\n            self?.doSomething()\n        }\n        \n        // Conserver et lancer\n        workItem = item\n        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: item)\n    }\n    \n    func cancelDelayedAction() {\n        workItem?.cancel()\n        workItem = nil\n        print("Tâche annulée")\n    }\n    \n    func doSomething() {\n        // Votre code\n    }\n}\n\n// Utilisation\nlet task = DelayedTask()\ntask.scheduleDelayedAction()\n// Annuler après 1 seconde\nDispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n    task.cancelDelayedAction()\n}
\n\n

Notez l'utilisation de [weak self] — c'est obligatoire pour éviter les fuites mémoire en Swift. Le délai peut survivre au contrôleur si la référence n'est pas affaiblie.

\n\n

3. Timer.scheduledTimer : délai avec répétition

\n

Les timers Swift ne servent pas uniquement pour les tâches répétitives. On peut créer un timer à usage unique avec un délai. Avantage : le timer se désactive facilement et peut être mis en pause.

\n\n
class TimerExample {\n    var timer: Timer?\n    \n    func startDelayedAction() {\n        // Timer à usage unique après 1,5 seconde\n        timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in\n            print("Timer déclenché après 1,5 sec")\n            self?.updateUI()\n        }\n    }\n    \n    func stopTimer() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    func updateUI() {\n        // Mettre à jour l'interface\n    }\n}
\n\n

Quand utiliser Timer

\n