@AppStorage ve SwiftUI — co to je, UserDefaults a ukládání nastavení

Autor: IT Sectr Publikováno: 2026-06-25 Doba čtení: 7 min

@AppStorage ve SwiftUI — property wrapper pro práci s UserDefaults, který automaticky synchronizuje hodnotu s UI. Při změně vlastnosti deklarované prostřednictvím @AppStorage je nová hodnota okamžitě uložena do UserDefaults, a když se UserDefaults změní zvenčí — widgetem nebo rozšířením — View se automaticky překreslí. Podle Apple Developer Documentation (2025), @AppStorage podporuje String, Int, Double, Bool, Data, URL a jejich volitelné verze, čímž poskytuje reaktivní ukládání uživatelských nastavení bez ručního kódu pozorování.

Hlavní body

  • @AppStorage — property wrapper pro reaktivní práci s UserDefaults ve SwiftUI
  • Automatické ukládání — hodnota se zapisuje do UserDefaults při každé změně
  • Automatická aktualizace UI — View se překreslí při změně UserDefaults z libovolného zdroje
  • Podporované typy: String, Int, Double, Bool, Data, URL a volitelné verze
  • Výchozí hodnota se nastavuje v deklaraci a používá se při prvním spuštění

Co je @AppStorage ve SwiftUI?

@AppStorage je property wrapper představený společností Apple v iOS 14, který propojuje vlastnost View s klíčem v UserDefaults. Při čtení vlastnosti SwiftUI načte hodnotu z UserDefaults na základě zadaného klíče. Při zápisu — uloží novou hodnotu a upozorní View na nutnost překreslení.

Před příchodem @AppStorage museli vývojáři ručně číst UserDefaults v onAppear, přihlásit se k odběru oznámení UserDefaults.didChangeNotification a aktualizovat @State při změnách. @AppStorage automatizuje celý cyklus: deklarace na jednom řádku nahrazuje 15–20 řádků boilerplate kódu. Navíc @AppStorage poskytuje obousměnou synchronizaci — pokud je hodnota UserDefaults změněna z jiného procesu (např. App Extension nebo Widget), View stejně obdrží aktualizaci.

Architektonicky je @AppStorage implementován jako DynamicProperty, což umožňuje SwiftUI sledovat závislosti a překreslit View při změně pozorované hodnoty. To jej činí ideálním pro ukládání uživatelských nastavení: jazyk rozhraní, zapínání/vypínání funkcí, naposledy vybraná záložka, uživatelské jméno.

@AppStorage vs UserDefaults: srovnání

Přestože @AppStorage pod kapotou používá UserDefaults, přístupy k práci s úložištěm se zásadně liší. UserDefaults je nízkoúrovňové API vyžadující ruční správu čtení, zápisu a oznámení o změnách. @AppStorage je SwiftUI abstrakce poskytující reaktivní chování ihned po vyjmutí z krabice.

UserDefaults je vhodný pro jednorázové operace: načítání nastavení při startu aplikace, zápis analytiky, ukládání tokenů do mezipaměti. @AppStorage — pro nastavení, která by měla reaktivně aktualizovat UI: přepínače motivů, výběr jazyka, ukládání stavu rozhraní. Přímé použití UserDefaults uvnitř View je antivzor, protože View se o změnách nedozví bez dalšího přihlášení k odběru.

Parametr@AppStorageUserDefaults
ReaktivitaAutomatickáVyžaduje přihlášení k oznámením
Boilerplate1 řádek na vlastnost15–20 řádků na vlastnost
TypyString, Int, Double, Bool, Data, URLVšechny typy + archivované objekty
Vlastní typyPřes RawRepresentablePřes NSKeyedArchiver
App ExtensionAutomatická synchronizaceRuční přihlášení

Pro jednoduchá nastavení s reaktivním UI je @AppStorage preferovanou volbou. Pro složitá data (pole, slovníky, vlastní objekty) použijte kombinaci UserDefaults s @State a ručním přihlášením ke změnám, nebo přejděte na SwiftData / Core Data pro strukturované ukládání.

Podporované datové typy

@AppStorage podporuje standardní typy, které UserDefaults může přímo serializovat: String, Int, Double, Bool, Data, URL. Pro každý typ existuje volitelná verze (String?, Int?, Double?, Bool?, Data?, URL?), která umožňuje rozlišení mezi „nenastaveno” a „prázdná hodnota”.

Pro ukládání vlastních typů vyhovujících protokolu RawRepresentable funguje @AppStorage také automaticky. Pokud má enum rawValue typu String nebo Int, lze jej použít přímo: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI automaticky serializuje/deserializuje hodnotu prostřednictvím 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("Spuštěno \(launchCount) krát")
        }
    }
}

V příkladu jsou použity různé typy @AppStorage: String s výchozí hodnotou „Guest”, Int pro poĈítadlo spuštění, Bool pro tmavý motiv, enum AppTheme s rawValue typu String a volitelný Date? pro čas posledního otevření. Každá vlastnost je vázána na klíč UserDefaults uvedený jako první argument. Výchozí hodnota se použije, pokud klíč v úložišti při prvním spuštění chybí.

Pozorování změn Store

Jednou z klíčových výhod @AppStorage — automatické pozorování změn UserDefaults z libovolného zdroje. Pokud App Extension nebo Widget změní hodnotu, @AppStorage v rodičovské aplikaci obdrží oznámení a překreslí View. Toho je dosaženo prostřednictvím mechanismu KVO (Key-Value Observing), který @AppStorage automaticky nastaví na UserDefaults.didChangeNotification.

V praxi to znamená, že pokud uživatel změní nastavení ve Widgetu (např. zapne tmavý motiv), aplikace tuto změnu okamžitě převezme. Podobně funguje synchronizace mezi hlavní aplikací a Share Extension, Watch App nebo Today Widget. Vývojář nemusí psát kód pro meziprocesovou výměnu dat — @AppStorage to dělá automaticky.

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("Tmavý režim změněn na \(newValue)")
                }
        }
    }
}

Toggle je propojen s $isDarkMode prostřednictvím @AppStorage. Při přepnutí je hodnota automaticky uložena do UserDefaults pod klíčem „isDarkMode”. Modifikátor .onChange umožňuje provést vedlejší akci při změně — například odeslat analytiku nebo aktualizovat UI jiných obrazovek. Pokud Widget změní stejný klíč, @AppStorage také zavolá onChange, čímž zajistí konzistenci stavu.

Příklady kódu @AppStorage

Podívejme se na úplnou obrazovku nastavení aplikace, která používá @AppStorage pro ukládání všech konfigurací. Formulář obsahuje sekce s různými typy nastavení: textová pole, přepínače, počítadla — všechny hodnoty jsou automaticky ukládány do 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("Předvolby")) {
                    Toggle("Enable notifications",
                           isOn: $notificationsEnabled)
                    Stepper("Max results: \(maxResults)",
                           value: $maxResults,
                           in: 10...100,
                           step: 5)
                }

                Section {
                    Button("Resetovat nastavení") {
                        UserDefaults.standard.removePersistentDomain(
                            forName: Bundle.main.bundleIdentifier!)
                    }
                    .tint(.red)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Formulář obsahuje čtyři vlastnosti @AppStorage různých typů: String pro jméno, Bool pro oznámení, Int pro počet výsledků a String pro vybranou záložku. Všechny ovládací prvky jsou propojeny s vlastnostmi prostřednictvím Binding ($displayName, $notificationsEnabled atd.). Tlačítko „Reset settings” resetuje všechna UserDefaults, odstraní doménu aplikace — poté se @AppStorage automaticky vrátí k výchozím hodnotám.

Synchronizace @AppStorage s 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 = "systém"

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

    var body: some View {
        Form {
            Picker("Widget theme", selection: $widgetTheme) {
                Text("Systém").tag("system")
                Text("Světlý").tag("světlý")
                Text("Tmavý").tag("tmavý")
            }
            Picker("Accent color", selection: $widgetColor) {
                Text("Modrá").tag("blue")
                Text("Zelená").tag("zelená")
                Text("Červená").tag("červená")
            }
        }
    }
}

Pro App Group (sdílené úložiště mezi aplikací a rozšířeními) @AppStorage přijímá parametr store: UserDefaults(suiteName:). Hodnoty jsou ukládány do sdíleného kontejneru přístupného hlavní aplikaci, Widgetu, Watch App a dalším rozšířením stejné skupiny. Widget může číst tato nastavení a při změně v aplikaci se Widget automaticky aktualizuje prostřednictvím mechanismu pozorování UserDefaults.

Často kladené otázky

Jaký je rozdíl mezi @AppStorage a @State?

@State ukládá hodnotu pouze v paměti a resetuje se při restartu aplikace. @AppStorage ukládá hodnotu do UserDefaults a obnoví ji při dalším spuštění. Použijte @State pro dočasná data obrazovky, @AppStorage — pro nastavení, která mají přežít restart.

Lze použít @AppStorage s Enum?

Ano, pokud Enum implementuje protokol RawRepresentable s rawValue typu String nebo Int. Příklad: @AppStorage("theme") var theme: AppTheme = .system. SwiftUI automaticky serializuje enum prostřednictvím rawValue a obnoví jej při načtení.

Jak vymazat všechny hodnoty @AppStorage?

Zavolejte UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) pro standardní úložiště nebo removeObject(forKey:) pro konkrétní klíč. Po vymazání se všechny vlastnosti @AppStorage vrátí k výchozím hodnotám uvedeným v deklaraci.

Funguje @AppStorage s App Extensions?

Ano, pro synchronizaci mezi aplikací a rozšířeními použijte App Group: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Widget, Share Extension a Watch App mohou číst a zapisovat do stejného UserDefaults a změny jsou automaticky sledovány.

Jaké množství dat lze ukládat do @AppStorage?

@AppStorage používá UserDefaults, který je určen pro malá množství dat: nastavení, tokeny, počítadla. Doporučený limit je do 100 KB na aplikaci. Pro strukturovaná nebo velká data (pole objektů, mediální soubory) použijte SwiftData, Core Data nebo souborový systém.

Shrnutí

  • @AppStorage — property wrapper pro reaktivní ukládání nastavení v UserDefaults
  • Automatické ukládání a automatická aktualizace UI při změně hodnoty z libovolného zdroje
  • Podporuje String, Int, Double, Bool, Data, URL a RawRepresentable enums
  • Výchozí hodnota se nastavuje v deklaraci a obnovuje se při prvním spuštění
  • App Group umožňuje synchronizaci @AppStorage mezi aplikací a rozšířeními
  • UserDefaults je vhodný jen pro malá množství dat — do 100 KB
  • Použijte @AppStorage pro uživatelská nastavení, @State — pro dočasné stavy obrazovky

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také