@AppStorage a SwiftUI-ban — property wrapper a UserDefaults-szal való munkához, amely automatikusan szinkronizálja az értéket a UI-val. A @AppStorage-on keresztül deklarált tulajdonság megváltoztatásakor az új érték azonnal elmentődik a UserDefaults-ba, és amikor a UserDefaults külről — widget vagy bővítmény által — megváltozik, a View automatikusan újarajzolódik. A Apple Developer Documentation (2025) szerint a @AppStorage támogatja a String, Int, Double, Bool, Data, URL és azok opcionális verzióit, reaktív felhasználói beállítások tárolását biztosítva kézi megfigyelő kód nélkül.
Főbb pontok
@AppStorage egy property wrapper, amelyet az Apple az iOS 14-ben vezetett be, és összeköti a View tulajdonságát egy UserDefaults-beli kulccsal. A tulajdonság olvasásakor a SwiftUI betölti az értéket a UserDefaults-ból a megadott kulcs alapján. Íráskor — elmenti az új értéket, és értesíti a View-t az újarajzolás szükségességéről.
Az @AppStorage megjelenése előtt a fejlesztőknek kézzel kellett olvasniuk a UserDefaults-ot az onAppear-ben, feliratkozniuk a UserDefaults.didChangeNotification értesítésre és frissíteniük a @State-et a változásoknál. Az @AppStorage automatizálja a teljes ciklust: egy soros deklaráció 15–20 sor boilerplate kódot helyettesít. Ráadásul a @AppStorage kétirányú szinkronizációt biztosít — ha a UserDefaults érték egy másik folyamatból (pl. App Extension vagy Widget) megváltozik, a View akkor is megkapja a frissítést.
Architektúráját tekintve az @AppStorage DynamicProperty-ként van megvalósítva, ami lehetővé teszi a SwiftUI számára a függőségek nyomon követését és a View újarajzolását a megfigyelt érték változásakor. Ez ideálissá teszi a felhasználói beállítások tárolására: interfész nyelve, funkciók be-/kikapcsolása, utoljára kiválasztott fül, felhasználónév.
Bár az @AppStorage a motorháztető alatt UserDefaults-ot használ, a tárolással való munka megközelítései alapvetően különböznek. A UserDefaults egy alacsony szintű API, amely az olvasás, írás és változási értesítések kézi kezelését igényli. Az @AppStorage egy SwiftUI absztrakció, amely készreaktív viselkedést nyújt a dobozból.
A UserDefaults alkalmi műveletekhez alkalmas: beállítások betöltése az alkalmazás indításakor, analitika írása, tokenek gyorsítótárba helyezése. @AppStorage — olyan beállításokhoz, amelyeknek reaktívan kell frissíteniük a UI-t: témakapcsolók, nyelvválasztás, interfész állapotának mentése. A UserDefaults közvetlen használata a View-n belül antipattern, mert a View nem értesül a változásokról további feliratkozás nélkül.
| Paraméter | @AppStorage | UserDefaults |
|---|---|---|
| Reaktivitás | Automatikus | Értesítésekre feliratkozást igényel |
| Boilerplate | 1 sor tulajdonságonként | 15–20 sor tulajdonságonként |
| Típusok | String, Int, Double, Bool, Data, URL | Minden típus + archivált objektumok |
| Egyedi típusok | RawRepresentable-on keresztül | NSKeyedArchiver-en keresztül |
| App Extension | Automatikus szinkronizáció | Kézi feliratkozás |
Egyszerű beállításokhoz reaktív UI-val a @AppStorage az előnyben részesített választás. Összetett adatokhoz (tömbök, szótárak, egyedi objektumok) használja a UserDefaults és a @State kombínációját kézi változás feliratkozással, vagy váltson a SwiftData / Core Data-ra strukturált tároláshoz.
Az @AppStorage támogatja a szabvány típusokat, amelyeket a UserDefaults közvetlenül tud szerializálni: String, Int, Double, Bool, Data, URL. Minden típushoz létezik opcionális verzió (String?, Int?, Double?, Bool?, Data?, URL?), amely lehetővé teszi a „nincs beállítva” és „üres érték” megkülönböztetését.
A RawRepresentable protokollnak megfelelő egyedi típusok tárolásához az @AppStorage szintén automatikusan működik. Ha egy enum rawValue típusa String vagy Int, közvetlenül használható: @AppStorage("theme") var theme: AppTheme = .system. A SwiftUI automatikusan szerializálja/deszerializálja az értéket a rawValue-n keresztül.
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) alkalommal indítva")
}
}
}
A példában különböző @AppStorage típusok szerepelnek: String a „Vendég” alapértelmezett értékkel, Int az indításszámlálóhoz, Bool a sötét témához, AppTheme enum rawValue típusú String és opcionális Date? az utolsó megnyitás idejéhez. Minden tulajdonság az első argumentumként megadott UserDefaults kulcshoz van kötve. Az alapértelmezett érték akkor használatos, ha a kulcs nem létezik a tárolóban az első indításkor.
Az @AppStorage egyik fő előnye — a UserDefaults változásainak automatikus megfigyelése bármely forrásból. Ha egy App Extension vagy Widget megváltoztat egy értéket, a szülő alkalmazásban az @AppStorage értesítést kap és újarajzolja a View-t. Ez a KVO (Key-Value Observing) mechanizmuson keresztül érhető el, amelyet az @AppStorage automatikusan beállít a UserDefaults.didChangeNotification-ra.
A gyakorlatban ez azt jelenti, hogy ha a felhasználó megváltoztat egy beállítást a Widget-ben (pl. bekapcsolja a sötét témát), az alkalmazás azonnal átveszi ezt a változást. Hasonlóan működik a szinkronizáció a fő alkalmazás és a Share Extension, Watch App vagy Today Widget között. A fejlesztőnek nem kell kódot írnia a folyamatok közötti adatcseréhez — az @AppStorage ezt automatikusan megteszi.
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("Sötét mód változása: \(newValue)")
}
}
}
}
A Toggle a @AppStorage-on keresztül a $isDarkMode-hoz van kötve. Átkapcsoláskor az érték automatikusan elmentődik a UserDefaults-ba az „isDarkMode” kulcs alatt. A .onChange módosító lehetővé teszi mellékhatás végrehajtását változáskor — például analitika küldését vagy más képernyők UI-jának frissítését. Ha a Widget ugyanazt a kulcsot változtatja meg, az @AppStorage szintén meghívja az onChange-t, biztosítva az állapot konzisztenciáját.
Nézzünk meg egy teljes alkalmazásbeállítás képernyőt, amely az @AppStorage-t használja az összes konfiguráció tárolására. Az űrlap különböző típusú beállításokkal rendelkező szekciókat tartalmaz: szövegmezők, kapcsolók, számlálók — minden érték automatikusan elmentődik a UserDefaults-ba.
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("Beállítások")) {
Toggle("Enable notifications",
isOn: $notificationsEnabled)
Stepper("Max results: \(maxResults)",
value: $maxResults,
in: 10...100,
step: 5)
}
Section {
Button("Beállítások visszaállítása") {
UserDefaults.standard.removePersistentDomain(
forName: Bundle.main.bundleIdentifier!)
}
.tint(.red)
}
}
.navigationTitle("Settings")
}
}
}
Az űrlap négy különböző típusú @AppStorage tulajdonságot tartalmaz: String a névhez, Bool az értesítésekhez, Int az eredmények számához és String a kiválasztott fülhöz. Minden vezérlő Binding-on keresztül van a tulajdonságokhoz kötve ($displayName, $notificationsEnabled stb.). A „Reset settings” gomb minden UserDefaults-ot visszaállít, törölve az alkalmazás doménjét — ezt követően az @AppStorage automatikusan visszatér az alapértelmezett értékekre.
struct SharedSettingsView: View {
let sharedDefaults = UserDefaults(suiteName: "group.com.example.app")
@AppStorage("widgetTheme", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetTheme: String = "rendszer"
@AppStorage("widgetColor", store: UserDefaults(suiteName: "group.com.example.app")!)
var widgetColor: String = "kék"
var body: some View {
Form {
Picker("Widget theme", selection: $widgetTheme) {
Text("Rendszer").tag("system")
Text("Világos").tag("világos")
Text("Sötét").tag("sötét")
}
Picker("Accent color", selection: $widgetColor) {
Text("Kék").tag("blue")
Text("Zöld").tag("zöld")
Text("Piros").tag("piros")
}
}
}
}
Az App Group (megosztott tároló az alkalmazás és bővítmények között) számára az @AppStorage elfogadja a store: UserDefaults(suiteName:) paramétert. Az értékek egy megosztott konténerben tárolódnak, amely elérhető a fő alkalmazás, Widget, Watch App és más, ugyanazon csoportba tartozó bővítmények számára. A Widget olvashatja ezeket a beállításokat, és az alkalmazásban történő változáskor a Widget automatikusan frissül a UserDefaults megfigyelő mechanizmusán keresztül.
Gyakran Ismételt Kérdések
A @State csak memóriában tárolja az értéket és az alkalmazás újraindításakor visszaállítódik. Az @AppStorage az értéket a UserDefaults-ban menti el és a következő indításkor visszaállítja. Használja a @State-et ideiglenes képernyőadatokhoz, az @AppStorage-ot olyan beállításokhoz, amelyeknek túl kell élniük az újraindítást.
Igen, ha az Enum megvalósítja a RawRepresentable protokollt rawValue típusú String vagy Int értékkel. Példa: @AppStorage("theme") var theme: AppTheme = .system. A SwiftUI automatikusan szerializálja az enum-ot a rawValue-n keresztül és visszaállítja betöltéskor.
Hívja meg a UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) függvényt a szabvány tárolóhoz vagy a removeObject(forKey:) függvényt egy adott kulcshoz. A törlés után minden @AppStorage tulajdonság visszatér a deklarációban megadott alapértelmezett értékekre.
Igen, az alkalmazás és bővítmények közötti szinkronizációhoz használja az App Group-ot: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). A Widget, Share Extension és Watch App olvashat és írhat ugyanabban a UserDefaults-ban, és a változások automatikusan követhetők.
Az @AppStorage a UserDefaults-ot használja, amely kis mennyiségű adatokhoz készült: beállítások, tokenek, számlálók. Az ajánlott korlát alkalmazásonként 100 KB. Strukturált vagy nagy adatokhoz (objektumtömbök, médiafájlok) használja a SwiftData, Core Data vagy fájlrendszert.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is