@AppStorage i SwiftUI — vad är det, UserDefaults och lagring av inställningar

Författare: IT Sectr Publicerad: 2026-06-25 Lästid: 7 min

@AppStorage i SwiftUI — property wrapper för att arbeta med UserDefaults, som automatiskt synkroniserar värdet med UI. När en egenskap som deklareras via @AppStorage ändras sparas det nya värdet omedelbart i UserDefaults, och när UserDefaults ändras externt — av en widget eller ett tillägg — ritas View om automatiskt. Enligt Apple Developer Documentation (2025) stödjer @AppStorage String, Int, Double, Bool, Data, URL och deras valfria versioner, vilket ger reaktiv lagring av användarinställningar utan manuell övervakningskod.

Huvudpunkter

  • @AppStorage — property wrapper för reaktivt arbete med UserDefaults i SwiftUI
  • Autospara — värdet skrivs till UserDefaults vid varje ändring
  • Automatisk UI-uppdatering — View ritas om när UserDefaults ändras från någon källa
  • Stödda typer: String, Int, Double, Bool, Data, URL och valfria versioner
  • Standardvärde anges i deklarationen och används vid första starten

Vad är @AppStorage i SwiftUI?

@AppStorage är en property wrapper som introducerades av Apple i iOS 14, som kopplar en View-egenskap till en nyckel i UserDefaults. När egenskapen läses laddar SwiftUI värdet från UserDefaults baserat på den angivna nyckeln. Vid skrivning — sparar det nya värdet och meddelar View om behovet av omritning.

Före @AppStorage var utvecklare tvungna att manuellt läsa UserDefaults i onAppear, prenumerera på UserDefaults.didChangeNotification och uppdatera @State vid ändringar. @AppStorage automatiserar hela cykeln: en deklaration på en rad ersätter 15–20 rader boilerplate-kod. Dessutom ger @AppStorage tvåvägssynkronisering — om UserDefaults-värdet ändras från en annan process (t.ex. App Extension eller Widget), kommer View ändå att få uppdateringen.

Arkitekturmässigt är @AppStorage implementerad som DynamicProperty, vilket gör att SwiftUI kan spåra beroenden och rita om View när det observerade värdet ändras. Detta gör den idealisk för lagring av användarinställningar: gränssnittsspråk, aktivering/avaktivering av funktioner, senast vald flik, användarnamn.

@AppStorage vs UserDefaults: jämförelse

Även om @AppStorage använder UserDefaults under huven skiljer sig tillvägagångssätten för lagring i grunden. UserDefaults är ett lågnivå-API som kräver manuell hantering av läsning, skrivning och ändringsmeddelanden. @AppStorage är en SwiftUI-abstraktion som ger reaktivt beteende direkt ur lådan.

UserDefaults är lämplig för engångsoperationer: ladda inställningar vid appstart, skriva analysdata, cachelagra tokens. @AppStorage — för inställningar som måste uppdatera UI reaktivt: temaväxlare, språkval, spara gränssnittstillstånd. Direkt användning av UserDefaults inuti en View är ett anti-mönster, eftersom View inte får reda på ändringar utan ytterligare prenumeration.

Parameter@AppStorageUserDefaults
ReaktivitetAutomatiskKräver prenumeration på meddelanden
Boilerplate1 rad per egenskap15–20 rader per egenskap
TyperString, Int, Double, Bool, Data, URLAlla typer + arkiverade objekt
Anpassade typerVia RawRepresentableVia NSKeyedArchiver
App ExtensionAutomatisk synkroniseringManuell prenumeration

För enkla inställningar med reaktivt UI är @AppStorage det föredragna valet. För komplexa data (arrayer, ordböcker, anpassade objekt) använd en kombination av UserDefaults med @State och manuell prenumeration på ändringar, eller byt till SwiftData / Core Data för strukturerad lagring.

Stödda datatyper

@AppStorage stödjer standardtyperna som UserDefaults kan serialisera direkt: String, Int, Double, Bool, Data, URL. För varje typ finns en valfri version (String?, Int?, Double?, Bool?, Data?, URL?), som gör det möjligt att skilja mellan ”ej angivet” och ”ttomt värde”.

För lagring av anpassade typer som följer protokollet RawRepresentable fungerar @AppStorage också automatiskt. Om en enum har rawValue av typen String eller Int kan den användas direkt: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI serialiserar/deserialiserar automatiskt värdet via 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("Startad \(launchCount) gånger")
        }
    }
}

I exemplet används olika @AppStorage-typer: String med standardvärdet ”Guest”, Int för starträknaren, Bool för mörkt tema, enum AppTheme med rawValue av typen String och valfri Date? för senaste öppningstiden. Varje egenskap är bunden till en UserDefaults-nyckel som anges som första argument. Standardvärdet används om nyckeln saknas i lagringen vid första starten.

Observation av Store-ändringar

En av de viktigaste fördelarna med @AppStorage — automatisk observation av UserDefaults-ändringar från valfri källa. Om en App Extension eller Widget ändrar ett värde får @AppStorage i den överordnade applikationen ett meddelande och ritar om View. Detta uppnås genom KVO-mekanismen (Key-Value Observing), som @AppStorage automatiskt ställer in på UserDefaults.didChangeNotification.

I praktiken innebär detta att om en användare ändrar en inställning i Widget (t.ex. aktiverar mörkt tema), fångar applikationen omedelbart upp ändringen. Liknande synkronisering fungerar mellan huvudapplikationen och Share Extension, Watch App eller Today Widget. Utvecklaren behöver inte skriva kod för interprocessdataväxling — @AppStorage gör detta automatiskt.

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("Mörkt läge ändrat till \(newValue)")
                }
        }
    }
}

Toggle är kopplad till $isDarkMode via @AppStorage. Vid växling sparas värdet automatiskt i UserDefaults under nyckeln ”isDarkMode”. Modifieraren .onChange gör det möjligt att utföra en sidoeffekt vid ändring — till exempel skicka analysdata eller uppdatera UI för andra skärmar. Om Widget ändrar samma nyckel kommer @AppStorage också att anropa onChange, vilket säkerställer tillståndskonsistens.

@AppStorage kodexempel

Låt oss titta på en komplett inställningsskärm för applikationen som använder @AppStorage för att lagra alla konfigurationer. Formuläret innehåller sektioner med olika typer av inställningar: textfält, växlare, räknare — alla värden sparas automatiskt i UserDefaults.

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("Inställningar")) {
                    Toggle("Enable notifications",
                           isOn: $notificationsEnabled)
                    Stepper("Max results: \(maxResults)",
                           value: $maxResults,
                           in: 10...100,
                           step: 5)
                }

                Section {
                    Button("Återställ inställningar") {
                        UserDefaults.standard.removePersistentDomain(
                            forName: Bundle.main.bundleIdentifier!)
                    }
                    .tint(.red)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Formuläret innehåller fyra @AppStorage-egenskaper av olika typer: String för namn, Bool för meddelanden, Int för antal resultat och String för vald flik. Alla kontroller är kopplade till egenskaperna via Binding ($displayName, $notificationsEnabled etc.). Knappen ”Reset settings” återställer alla UserDefaults genom att ta bort applikationens domän — efter detta återgår @AppStorage automatiskt till standardvärdena.

Synkronisering av @AppStorage med 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 = "blått"

    var body: some View {
        Form {
            Picker("Widget theme", selection: $widgetTheme) {
                Text("System").tag("system")
                Text("Ljust").tag("ljust")
                Text("Mörkt").tag("mörkt")
            }
            Picker("Accent color", selection: $widgetColor) {
                Text("Blått").tag("blue")
                Text("Grönt").tag("grönt")
                Text("Rött").tag("rött")
            }
        }
    }
}

För App Group (delad lagring mellan applikationen och tillägg) accepterar @AppStorage parametern store: UserDefaults(suiteName:). Värden sparas i en delad behållare som är tillgänglig för huvudapplikationen, Widget, Watch App och andra tillägg i samma grupp. Widget kan läsa dessa inställningar, och vid ändring i applikationen uppdateras Widget automatiskt via UserDefaults observationsmekanism.

Vanliga frågor

Vad är skillnaden mellan @AppStorage och @State?

@State lagrar värdet endast i minnet och återställs vid omstart av applikationen. @AppStorage sparar värdet i UserDefaults och återställer det vid nästa start. Använd @State för temporära skärmdata, @AppStorage — för inställningar som ska överleva omstart.

Kan @AppStorage användas med Enum?

Ja, om Enum implementerar protokollet RawRepresentable med rawValue av typen String eller Int. Exempel: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI serialiserar automatiskt enum via rawValue och återställer det vid laddning.

Hur rensar man alla @AppStorage-värden?

Anropa UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) för standardlagring eller removeObject(forKey:) för en specifik nyckel. Efter rensning återgår alla @AppStorage-egenskaper till standardvärdena som anges i deklarationen.

Fungerar @AppStorage med App Extensions?

Ja, för synkronisering mellan applikationen och tillägg använd App Group: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Widget, Share Extension och Watch App kan läsa och skriva i samma UserDefaults, och ändringar spåras automatiskt.

Hur mycket data kan lagras i @AppStorage?

@AppStorage använder UserDefaults, som är avsett för små mängder data: inställningar, tokens, räknare. Rekommenderad gräns är upp till 100 KB per applikation. För strukturerad eller stor data (objektarrayer, mediafiler) använd SwiftData, Core Data eller filsystemet.

Sammanfattning

  • @AppStorage — property wrapper för reaktiv lagring av inställningar i UserDefaults
  • Autospara och automatisk UI-uppdatering när värdet ändras från valfri källa
  • Stödjer String, Int, Double, Bool, Data, URL och RawRepresentable enums
  • Standardvärde anges i deklarationen och återställs vid första starten
  • App Group möjliggör synkronisering av @AppStorage mellan applikation och tillägg
  • UserDefaults är endast lämplig för små mängder data — upp till 100 KB
  • Använd @AppStorage för användarinställningar, @State — för temporära skärmtillstånd

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också