Wie man deprecated keyWindow in iOS 13 behebt: vollständiger Leitfaden

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

«keyWindow» ist veraltet. Was tun?

\n\n

Wenn Sie jemals geschrieben haben:

\n\n
guard let window = UIApplication.shared.keyWindow else { return }
\n\n

…dann haben Sie sicherlich die gelbe Xcode-Warnung gesehen: «'keyWindow' was deprecated in iOS 13.0». Dies ist eine der häufigsten Fragen auf Stack Overflow (über 100.000 Aufrufe), und das aus gutem Grund – Apple hat die Regeln tatsächlich geändert.

\n\n

In diesem Artikel werden wir analysieren, warum dies passiert ist, und 4 Ansätze vergleichen, wie Sie das App-Fenster ohne die deprecated API erhalten. Sie erfahren, welche Methode für UIKit, SwiftUI, SceneDelegate geeignet ist und wann Sie welche verwenden sollten. Los geht's!

\n\n

Warum hat Apple keyWindow aufgegeben?

\n\n

Vor iOS 13 hatte eine App ein Hauptfenster – keyWindow. Alles war einfach: Man nimmt es und arbeitet damit. Aber mit dem Aufkommen von iPadOS und Multitasking (Split View, Slide Over) kann eine App mehrere Fenster gleichzeitig haben. Jedes Fenster wird von seiner eigenen UIWindowScene verwaltet. Der Begriff «Schlüsselfenster» wurde unscharf.

\n\n

Apple empfiehlt nun, das Fenster über die Szene (UIWindowScene) zu erhalten, zu der Ihr Controller oder View gehört.

\n\n

Vergleich der Ansätze: Vom Einfachen zum Richtigen

\n\n

Wir betrachten 4 Methoden, von «Warnung schnell unterdrücken» bis «nach Apple-Art». Wählen Sie die, die zu Ihrer Architektur passt.

\n\n

1. Schneller Fix: UIApplication.shared.windows.first(where:)

\n\n

Die beliebteste Antwort auf Stack Overflow ist die Verwendung der Eigenschaft windows anstelle von keyWindow:

\n\n
if let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {\n    // window verwenden\n}
\n\n

Vorteile:

\n
    \n
  • Minimale Code-Änderungen
  • \n
  • Funktioniert ab iOS 13+
  • \n
\n\n

Nachteile:

\n
    \n
  • Weiterhin unsicher bei mehreren Fenstern
  • \n
  • Kann nil zurückgeben, wenn das Fenster noch nicht erstellt wurde
  • \n
  • Apple markiert dies in einigen Kontexten weiterhin als «deprecated»
  • \n
\n\n

Wann verwenden: Nur für schnelle Prototypen oder wenn Sie definitiv nur ein Fenster haben (z. B. iPhone-App ohne Multi-Fenster-Funktionalität).

\n\n

2. Über SceneDelegate: Der richtige Weg für UIKit

\n\n

Ab iOS 13 hat Apple UISceneDelegate eingeführt. In der Methode scene(_:willConnectTo:options:) erhalten Sie eine UIWindowScene und können eine Referenz auf das Fenster speichern.

\n\n

Schritt 1: Deklarieren Sie in SceneDelegate.swift die Eigenschaft window:

\n\n
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

Schritt 2: Holen Sie sich das Fenster über die Szene:

\n\n
if let windowScene = view.window?.windowScene,\n   let window = windowScene.windows.first {\n    // window verwenden\n}
\n\n

Oder, wenn Sie das Hauptfenster an einer beliebigen Stelle in der App benötigen, speichern Sie eine Referenz auf den SceneDelegate und dessen window.

\n\n

Vorteile:

\n
    \n
  • Entspricht vollständig den Apple-Empfehlungen
  • \n
  • Funktioniert korrekt mit mehreren Fenstern
  • \n
  • Sicher für Multitasking auf dem iPad
  • \n
\n\n

Nachteile:

\n
    \n
  • Erfordert die Einrichtung von SceneDelegate (falls Sie noch nicht umgestiegen sind)
  • \n
  • Etwas mehr Code
  • \n
\n\n

3. Über UIWindowScene.activeWindow (iOS 15+)

\n\n

Ab iOS 15 hat UIWindowScene

Blogs

Buchempfehlungen