« keyWindow » est obsolète. Que faire ?
\n\nSi vous avez déjà écrit :
\n\nguard let window = UIApplication.shared.keyWindow else { return }\n\n…vous avez sûrement vu l'avertissement jaune de Xcode : « 'keyWindow' was deprecated in iOS 13.0 ». C'est l'une des questions les plus fréquentes sur Stack Overflow (plus de 100 000 vues), et pour cause — Apple a vraiment changé les règles du jeu.
\n\nDans cet article, nous allons voir pourquoi cela s'est produit et comparer 4 approches pour obtenir la fenêtre de l'application sans utiliser l'API obsolète. Vous découvrirez quelle méthode convient à UIKit, SwiftUI, SceneDelegate et quand utiliser chacune d'elles. C'est parti !
\n\nPourquoi Apple a-t-elle abandonné keyWindow ?
\n\nAvant iOS 13, l'application avait une fenêtre principale — keyWindow. Tout était simple : on la prenait et on travaillait. Mais avec l'arrivée d'iPadOS et du multitâche (Split View, Slide Over), une application peut avoir plusieurs fenêtres simultanément. Chaque fenêtre est gérée par son propre UIWindowScene. La notion de « fenêtre clé » est devenue floue.
Apple recommande désormais d'obtenir la fenêtre via la scène (UIWindowScene) à laquelle appartiennent votre contrôleur ou votre vue.
\n\nComparaison des approches : du simple au correct
\n\nNous allons examiner 4 méthodes, allant de « faire taire rapidement l'avertissement » à « faire comme Apple ». Choisissez celle qui correspond à votre architecture.
\n\n1. Correction rapide : UIApplication.shared.windows.first(where:)
\n\nLa réponse la plus populaire sur Stack Overflow est d'utiliser la propriété windows au lieu de keyWindow :
if let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {\n // utiliser window\n}\n\nAvantages :
\n- \n
- Minimum de modifications dans le code \n
- Fonctionne sur iOS 13+ \n
Inconvénients :
\n- \n
- Toujours pas sécurisé avec plusieurs fenêtres \n
- Peut retourner nil si la fenêtre n'est pas encore créée \n
- Apple marque toujours cela comme « deprecated » dans certains contextes \n
Quand l'utiliser : Uniquement pour un prototype rapide ou si vous avez exactement une fenêtre (par exemple, une application iPhone sans multi-fenêtres).
\n\n2. Via SceneDelegate : la bonne approche pour UIKit
\n\nDepuis iOS 13, Apple a introduit UISceneDelegate. Dans la méthode scene(_:willConnectTo:options:), vous recevez un UIWindowScene et pouvez conserver une référence à la fenêtre.
Étape 1 : Dans SceneDelegate.swift, déclarez la propriété window :
class SceneDelegate: UIResponder, UIWindowSceneDelegate {\n\n var window: UIWindow?\n\n func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {\n guard let windowScene = (scene as? UIWindowScene) else { return }\n window = UIWindow(windowScene: windowScene)\n window?.rootViewController = ViewController()\n window?.makeKeyAndVisible()\n }\n}\n\nÉtape 2 : Obtenez la fenêtre via la scène :
\n\nif let windowScene = view.window?.windowScene,\n let window = windowScene.windows.first {\n // utiliser window\n}\n\nOu, si vous avez besoin de la fenêtre principale n'importe où dans l'application, conservez une référence au SceneDelegate et à sa window.
Avantages :
\n- \n
- Totalement conforme aux recommandations d'Apple \n
- Fonctionne correctement avec plusieurs fenêtres \n
- Sécurisé pour le multitâche sur iPad \n
Inconvénients :
\n- \n
- Nécessite la configuration de SceneDelegate (si vous n'avez pas encore migré) \n
- Un peu plus de code \n
3. Via UIWindowScene.activeWindow (iOS 15+)
\n\nDepuis iOS 15, UIWindowScene
Blogs
Book Recommendations
Lire aussi
Rust 2028 : principales tendances et prévisions d'évolution du langage
Optimisation des performances des applications Go : conseils et exemples
Code review en Go : que vérifier et comment donner un retour
Type never en TypeScript : comment corriger l'erreur "not assignable to parameter"
Couverture de code par les tests en C# : des métriques à la qualité