@AppStorage in SwiftUI — was ist das, UserDefaults und Speicherung von Einstellungen

Autor: IT Sectr Veröffentlicht: 2026-06-25 Lesezeit: 7 Min.

@AppStorage in SwiftUI ist ein property wrapper für die Arbeit mit UserDefaults, der den Wert automatisch mit der UI synchronisiert. Wenn sich eine mit @AppStorage deklarierte Eigenschaft ändert, wird der neue Wert sofort in UserDefaults gespeichert, und wenn UserDefaults extern geändert wird — durch ein Widget oder eine Erweiterung — wird die View automatisch neu gezeichnet. Laut Apple Developer Documentation (2025) unterstützt @AppStorage String, Int, Double, Bool, Data, URL und deren optionale Versionen und bietet reaktive Speicherung von Benutzereinstellungen ohne manuellen Beobachtungscode.

Wichtige Punkte

  • @AppStorage — property wrapper für reaktive Arbeit mit UserDefaults in SwiftUI
  • Automatisches Speichern — der Wert wird bei jeder Änderung in UserDefaults geschrieben
  • Automatisches UI-Update — die View wird neu gezeichnet, wenn UserDefaults von einer beliebigen Quelle geändert wird
  • Unterstützte Typen: String, Int, Double, Bool, Data, URL und optionale Versionen
  • Standardwert wird in der Deklaration festgelegt und beim ersten Start verwendet

Was ist @AppStorage in SwiftUI?

@AppStorage ist ein von Apple in iOS 14 eingeführter property wrapper, der eine View-Eigenschaft an einen Schlüssel in UserDefaults bindet. Beim Lesen der Eigenschaft lädt SwiftUI den Wert aus UserDefaults über den angegebenen Schlüssel. Beim Schreiben speichert es den neuen Wert und benachrichtigt die View über die erforderliche Neuzeichnung.

Vor @AppStorage mussten Entwickler UserDefaults manuell in onAppear lesen, UserDefaults.didChangeNotification abonnieren und @State bei Änderungen aktualisieren. @AppStorage automatisiert den gesamten Zyklus: Eine einzeilige Deklaration ersetzt 15–20 Zeilen Boilerplate-Code. Darüber hinaus bietet @AppStorage bidirektionale Synchronisation — wenn der UserDefaults-Wert von einem anderen Prozess (z.B. App Extension oder Widget) geändert wird, erhält die View trotzdem das Update.

Architektonisch ist @AppStorage als DynamicProperty implementiert, was SwiftUI ermöglicht, Abhängigkeiten zu verfolgen und die View bei Änderung des beobachteten Werts neu zu zeichnen. Dies macht es ideal für die Speicherung von Benutzereinstellungen: Oberflächensprache, Aktivieren/Deaktivieren von Funktionen, letzter ausgewählter Tab, Benutzername.

@AppStorage vs UserDefaults: Vergleich

Obwohl @AppStorage intern UserDefaults verwendet, unterscheiden sich die Ansätze zur Arbeit mit dem Speicher grundlegend. UserDefaults ist eine Low-Level-API, die manuelle Verwaltung von Lese-, Schreib- und Änderungsbenachrichtigungen erfordert. @AppStorage ist eine SwiftUI-Abstraktion, die reaktives Verhalten out of the box bietet.

UserDefaults eignet sich für einmalige Operationen: Laden von Einstellungen beim App-Start, Schreiben von Analysen, Zwischenspeichern von Tokens. @AppStorage ist für Einstellungen gedacht, die die UI reaktiv aktualisieren sollen: Theme-Umschalter, Sprachauswahl, Speichern des Oberflächenzustands. Die direkte Verwendung von UserDefaults in einer View ist ein Antipattern, da die View ohne zusätzliches Abonnement nichts von Änderungen erfährt.

Parameter@AppStorageUserDefaults
ReaktivitätAutomatischErfordert Abonnement von Benachrichtigungen
Boilerplate1 Zeile pro Eigenschaft15–20 Zeilen pro Eigenschaft
TypenString, Int, Double, Bool, Data, URLAlle Typen + archivierte Objekte
Benutzerdefinierte TypenÜber RawRepresentableÜber NSKeyedArchiver
App ExtensionAutomatische SynchronisationManuelles Abonnement

Für einfache Einstellungen mit reaktiver UI ist @AppStorage die bevorzugte Wahl. Für komplexe Daten (Arrays, Dictionaries, benutzerdefinierte Objekte) verwenden Sie eine Kombination von UserDefaults mit @State und manuellem Änderungsabonnement oder wechseln Sie zu SwiftData / Core Data für strukturierte Speicherung.

Unterstützte Datentypen

@AppStorage unterstützt Standardtypen, die UserDefaults direkt serialisieren kann: String, Int, Double, Bool, Data, URL. Für jeden Typ gibt es eine optionale Version (String?, Int?, Double?, Bool?, Data?, URL?), die eine Unterscheidung zwischen „nicht gesetzt“ und „leerer Wert“ ermöglicht.

Für die Speicherung benutzerdefinierter Typen, die dem RawRepresentable-Protokoll entsprechen, funktioniert @AppStorage ebenfalls automatisch. Wenn ein Enum rawValue vom Typ String oder Int hat, kann es direkt verwendet werden: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI serialisiert/deserialisiert den Wert automatisch über rawValue.

swift
enum AppTheme: String {
    case system, light, dark
}

struct SettingsView: View {
    @AppStorage("username") var username: String = "Guest"
    @AppStorage("launchCount") var launchCount: Int = 0
    @AppStorage("isDarkMode") var isDarkMode: Bool = false
    @AppStorage("appTheme") var theme: AppTheme = .system
    @AppStorage("lastOpened") var lastOpened: Date? = nil

    var body: some View {
        Form {
            TextField("Username", text: $username)
            Toggle("Dark mode", isOn: $isDarkMode)
            Text("\(launchCount)-mal gestartet")
        }
    }
}

Das Beispiel verwendet verschiedene @AppStorage-Typen: String mit Standardwert „Guest“, Int für einen Startzähler, Bool für dunkles Thema, AppTheme-Enum mit rawValue vom Typ String und ein optionales Date? für die letzte Öffnungszeit. Jede Eigenschaft ist an einen UserDefaults-Schlüssel gebunden, der als erstes Argument angegeben wird. Der Standardwert wird verwendet, wenn der Schlüssel beim ersten Start nicht im Speicher vorhanden ist.

Beobachtung von Store-Änderungen

Einer der Hauptvorteile von @AppStorage ist die automatische Beobachtung von UserDefaults-Änderungen aus jeder Quelle. Wenn eine App Extension oder Widget einen Wert ändert, erhält @AppStorage in der übergeordneten App die Benachrichtigung und zeichnet die View neu. Dies wird durch den KVO-Mechanismus (Key-Value Observing) erreicht, den @AppStorage automatisch auf UserDefaults.didChangeNotification einrichtet.

In der Praxis bedeutet dies: Wenn der Benutzer eine Einstellung in einem Widget ändert (z.B. dunkles Thema aktiviert), übernimmt die App die Änderung sofort. Die gleiche Synchronisation funktioniert zwischen der Haupt-App und Share Extension, Watch App oder Today Widget. Der Entwickler muss keinen Code für den prozessübergreifenden Datenaustausch schreiben — @AppStorage erledigt dies automatisch.

swift
struct ThemeSettingView: View {
    @AppStorage("isDarkMode") var isDarkMode: Bool = false

    var body: some View {
        VStack {
            Toggle("Dark Mode", isOn: $isDarkMode)
                .onChange(of: isDarkMode) { oldValue, newValue in
                    print("Dark Mode geändert zu \(newValue)")
                }
        }
    }
}

Toggle ist über @AppStorage an $isDarkMode gebunden. Beim Umschalten wird der Wert automatisch unter dem Schlüssel „isDarkMode“ in UserDefaults gespeichert. Der .onChange-Modifikator ermöglicht die Ausführung eines Nebeneffekts bei Änderung — z.B. das Senden von Analysen oder das Aktualisieren der UI anderer Bildschirme. Wenn ein Widget denselben Schlüssel ändert, löst @AppStorage ebenfalls onChange aus und gewährleistet so die Zustandskonsistenz.

@AppStorage Codebeispiele

Betrachten wir einen vollwertigen App-Einstellungsbildschirm, der @AppStorage zum Speichern aller Konfigurationen verwendet. Das Formular enthält Abschnitte mit verschiedenen Einstellungstypen: Textfelder, Umschalter, Zähler — alle Werte werden automatisch in UserDefaults gespeichert.

swift
struct AppSettingsView: View {
    @AppStorage("displayName") var displayName = ""
    @AppStorage("notificationsEnabled") var notificationsEnabled = true
    @AppStorage("maxResults") var maxResults = 25
    @AppStorage("selectedTab") var selectedTab = "home"

    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Profil")) {
                    TextField("Display name", text: $displayName)
                }

                Section(header: Text("Einstellungen")) {
                    Toggle("Enable notifications",
                           isOn: $notificationsEnabled)
                    Stepper("Max results: \(maxResults)",
                           value: $maxResults,
                           in: 10...100,
                           step: 5)
                }

                Section {
                    Button("Einstellungen zurücksetzen") {
                        UserDefaults.standard.removePersistentDomain(
                            forName: Bundle.main.bundleIdentifier!)
                    }
                    .tint(.red)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Das Formular enthält vier @AppStorage-Eigenschaften verschiedener Typen: String für den Namen, Bool für Benachrichtigungen, Int für die Ergebnisanzahl und String für den ausgewählten Tab. Alle Steuerelemente sind über Binding ($displayName, $notificationsEnabled usw.) an die Eigenschaften gebunden. Die Schaltfläche „Reset settings“ löscht alle UserDefaults durch Entfernen der App-Domäne — danach kehrt @AppStorage automatisch zu den Standardwerten zurück.

@AppStorage-Synchronisation mit App Group

swift
struct SharedSettingsView: View {
    let sharedDefaults = UserDefaults(suiteName: "group.com.example.app")

    @AppStorage("widgetTheme", store: UserDefaults(suiteName: "group.com.example.app")!)
    var widgetTheme: String = "System"

    @AppStorage("widgetColor", store: UserDefaults(suiteName: "group.com.example.app")!)
    var widgetColor: String = "Blau"

    var body: some View {
        Form {
            Picker("Widget theme", selection: $widgetTheme) {
                Text("System").tag("system")
                Text("Hell").tag("Hell")
                Text("Dunkel").tag("Dunkel")
            }
            Picker("Accent color", selection: $widgetColor) {
                Text("Blau").tag("blue")
                Text("Grün").tag("Grün")
                Text("Rot").tag("Rot")
            }
        }
    }
}

Für App Group (gemeinsamer Speicher zwischen der App und Erweiterungen) akzeptiert @AppStorage den Parameter store: UserDefaults(suiteName:). Werte werden im gemeinsamen Container gespeichert, der für die Haupt-App, Widget, Watch App und andere Erweiterungen derselben Gruppe verfügbar ist. Ein Widget kann diese Einstellungen lesen, und wenn sie in der App geändert werden, wird das Widget über den UserDefaults-Beobachtungsmechanismus automatisch aktualisiert.

Häufig gestellte Fragen

Was ist der Unterschied zwischen @AppStorage und @State?

@State speichert den Wert nur im Speicher und wird beim Neustart der App zurückgesetzt. @AppStorage speichert den Wert in UserDefaults und stellt ihn beim nächsten Start wieder her. Verwenden Sie @State für temporäre Bildschirmdaten, @AppStorage für Einstellungen, die einen Neustart überdauern sollen.

Kann @AppStorage mit Enum verwendet werden?

Ja, wenn das Enum das RawRepresentable-Protokoll mit rawValue vom Typ String oder Int implementiert. Beispiel: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI serialisiert das Enum automatisch über rawValue und stellt es beim Laden wieder her.

Wie lösche ich alle @AppStorage-Werte?

Rufen Sie UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) für den Standardspeicher oder removeObject(forKey:) für einen bestimmten Schlüssel auf. Nach dem Löschen kehren alle @AppStorage-Eigenschaften zu den in der Deklaration angegebenen Standardwerten zurück.

Funktioniert @AppStorage mit App Extensions?

Ja, für die Synchronisation zwischen der App und Erweiterungen verwenden Sie App Group: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Widget, Share Extension und Watch App können in denselben UserDefaults lesen und schreiben, und Änderungen werden automatisch verfolgt.

Wie viele Daten können in @AppStorage gespeichert werden?

@AppStorage verwendet UserDefaults, das für kleine Datenmengen ausgelegt ist: Einstellungen, Tokens, Zähler. Die empfohlene Grenze liegt bei bis zu 100 KB pro App. Für strukturierte oder große Daten (Objekt-Arrays, Mediendateien) verwenden Sie SwiftData, Core Data oder das Dateisystem.

Zusammenfassung

  • @AppStorage — property wrapper für reaktive Einstellungsspeicherung in UserDefaults
  • Automatisches Speichern und automatisches UI-Update bei Wertänderung aus beliebiger Quelle
  • Unterstützt String, Int, Double, Bool, Data, URL und RawRepresentable-Enums
  • Standardwert wird in der Deklaration festgelegt und beim ersten Start wiederhergestellt
  • App Group ermöglicht die Synchronisation von @AppStorage zwischen App und Erweiterungen
  • UserDefaults ist nur für kleine Datenmengen geeignet — bis zu 100 KB
  • Verwenden Sie @AppStorage für Benutzereinstellungen, @State für temporäre Bildschirmzustände

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch