@AppStorage sa SwiftUI — ano ito, UserDefaults at pag-iimbak ng mga setting

May-akda: IT Sectr Nai-publish: 2026-06-25 Oras ng pagbabasa: 7 min

@AppStorage sa SwiftUI — property wrapper para sa pagtatrabaho sa UserDefaults, na awtomatikong nag-sync ng halaga sa UI. Kapag nagbago ang property na idineklara sa pamamagitan ng @AppStorage, ang bagong halaga ay agad na nai-save sa UserDefaults, at kapag ang UserDefaults ay nagbago mula sa labas — ng widget o extension — ang View ay awtomatikong muling iginuhit. Ayon sa Apple Developer Documentation (2025), ang @AppStorage ay sumusuporta sa String, Int, Double, Bool, Data, URL at kanilang mga opsyonal na bersyon, na nagbibigay ng reaktibong pag-iimbak ng mga setting ng user nang walang manu-manong code ng pagmamasid.

Mga Pangunahing Punto

  • @AppStorage — property wrapper para sa reaktibong pagtatrabaho sa UserDefaults sa SwiftUI
  • Awtomatikong pag-save — ang halaga ay isinusulat sa UserDefaults sa bawat pagbabago
  • Awtomatikong pag-update ng UI — ang View ay muling iginuhit kapag nagbago ang UserDefaults mula sa anumang pinagmulan
  • Mga suportadong uri: String, Int, Double, Bool, Data, URL at opsyonal na bersyon
  • Default na halaga ay itinakda sa deklarasyon at ginagamit sa unang pagtakbo

Ano ang @AppStorage sa SwiftUI?

@AppStorage ay isang property wrapper na ipinakilala ng Apple sa iOS 14, na nag-uugnay ng property ng View sa isang key sa UserDefaults. Kapag binabasa ang property, nilo-load ng SwiftUI ang halaga mula sa UserDefaults batay sa tinukoy na key. Kapag nagsusulat — ini-save ang bagong halaga at inaabisuhan ang View na kailangan itong muling iguhit.

Bago ang pagdating ng @AppStorage, ang mga developer ay kailangang manu-manong magbasa ng UserDefaults sa onAppear, mag-subscribe sa UserDefaults.didChangeNotification at mag-update ng @State sa mga pagbabago. Ang @AppStorage ay nag-automate ng buong cycle: isang deklarasyon sa isang linya ay pumapalit sa 15–20 linya ng boilerplate code. Higit pa rito, ang @AppStorage ay nagbibigay ng two-way na synchronisation — kung ang halaga ng UserDefaults ay binago mula sa ibang proseso (hal., App Extension o Widget), ang View ay makakatanggap pa rin ng update.

Sa arkitektura, ang @AppStorage ay ipinatupad bilang DynamicProperty, na nagpapahintulot sa SwiftUI na subaybayan ang mga dependency at muling iguhit ang View kapag nagbago ang naobserbahang halaga. Ginagawa nitong perpekto para sa pag-iimbak ng mga setting ng user: wika ng interface, pag-activate/pag-deactivate ng mga feature, huling napiling tab, username.

@AppStorage vs UserDefaults: paghahambing

Kahit na ang @AppStorage ay gumagamit ng UserDefaults sa ilalim ng hood, ang mga diskarte sa pagtatrabaho sa imbakan ay pangunahing nagkakaiba. Ang UserDefaults ay isang mababang antas na API na nangangailangan ng manu-manong pamamahala ng pagbabasa, pagsusulat at mga abiso ng pagbabago. Ang @AppStorage ay isang SwiftUI abstraction na nagbibigay ng reaktibong pag-uugali mula sa kahon.

Ang UserDefaults ay angkop para sa isang beses na operasyon: pag-load ng mga setting sa startup ng app, pagsusulat ng analytics, pag-cache ng mga token. @AppStorage — para sa mga setting na dapat reaktibong mag-update ng UI: mga switch ng tema, pagpili ng wika, pag-save ng estado ng interface. Ang direktang paggamit ng UserDefaults sa loob ng View ay isang antipattern, dahil hindi nalalaman ng View ang mga pagbabago nang walang karagdagang subscription.

Parameter@AppStorageUserDefaults
ReaktibidadAwtomatikoNangangailangan ng subscription sa mga abiso
Boilerplate1 linya bawat property15–20 linya bawat property
Mga uriString, Int, Double, Bool, Data, URLLahat ng uri + archive na bagay
Mga custom na uriSa pamamagitan ng RawRepresentableSa pamamagitan ng NSKeyedArchiver
App ExtensionAwtomatikong synchronisationManu-manong subscription

Para sa mga simpleng setting na may reaktibong UI, ang @AppStorage ang mas gustong pagpilian. Para sa mga kumplikadong data (array, diksyunaryo, custom na bagay) gumamit ng kumbinasyon ng UserDefaults na may @State at manu-manong subscription sa mga pagbabago, o lumipat sa SwiftData / Core Data para sa nakaayos na imbakan.

Mga suportadong uri ng data

Ang @AppStorage ay sumusuporta sa mga karaniwang uri na direktang mai-serialize ng UserDefaults: String, Int, Double, Bool, Data, URL. Para sa bawat uri ay may opsyonal na bersyon (String?, Int?, Double?, Bool?, Data?, URL?), na nagpapahintulot sa pag-iba sa pagitan ng “hindi nakatakda” at “walang laman na halaga”.

Para sa pag-iimbak ng mga custom na uri na sumusunod sa RawRepresentable protocol, ang @AppStorage ay awtomatikong gumagana. Kung ang enum ay may rawValue na uri ng String o Int, maaari itong gamitin nang direkta: @AppStorage("theme") var theme: AppTheme = .system. Awtomatikong sine-serialize/deserialize ng SwiftUI ang halaga sa pamamagitan ng 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("Inilunsad \(launchCount) beses")
        }
    }
}

Sa halimbawa, ginagamit ang iba’t ibang uri ng @AppStorage: String na may default na halaga na “Guest”, Int para sa startup counter, Bool para sa dark theme, enum AppTheme na may rawValue na uri ng String at opsyonal na Date? para sa huling oras ng pagbukas. Ang bawat property ay naka-link sa UserDefaults key na tinukoy bilang unang argumento. Ang default na halaga ay ginagamit kung ang key ay wala sa imbakan sa unang pagtakbo.

Pagmamasid sa mga pagbabago ng Store

Isa sa mga pangunahing bentahe ng @AppStorage — awtomatikong pagmamasid sa mga pagbabago ng UserDefaults mula sa anumang pinagmulan. Kung ang App Extension o Widget ay magbago ng halaga, ang @AppStorage sa parent na application ay makakatanggap ng abiso at muling iguguhit ang View. Ito ay nakakamit sa pamamagitan ng mekanismong KVO (Key-Value Observing), na awtomatikong itinatakda ng @AppStorage sa UserDefaults.didChangeNotification.

Sa praktika, nangangahulugan ito na kung babaguhin ng user ang isang setting sa Widget (hal., i-on ang dark theme), agad na kukunin ng application ang pagbabagong iyon. Ganoon din gumagana ang synchronisation sa pagitan ng pangunahing application at Share Extension, Watch App o Today Widget. Hindi kailangang magsulat ng code ang developer para sa inter-process na pagpapalitan ng data — awtomatikong ginagawa ito ng @AppStorage.

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("Binago ang dark mode sa \(newValue)")
                }
        }
    }
}

Ang Toggle ay konektado sa $isDarkMode sa pamamagitan ng @AppStorage. Kapag inilipat, ang halaga ay awtomatikong nai-save sa UserDefaults sa ilalim ng key na “isDarkMode”. Ang modifier na .onChange ay nagpapahintulot ng pagsasagawa ng side action sa pagbabago — halimbawa, pagpapadala ng analytics o pag-update ng UI ng iba pang mga screen. Kung babaguhin ng Widget ang parehong key, tatawagin din ng @AppStorage ang onChange, na tinitiyak ang consistency ng estado.

Mga halimbawa ng code ng @AppStorage

Tingnan natin ang isang kumpletong screen ng mga setting ng application na gumagamit ng @AppStorage para iimbak ang lahat ng configuration. Ang form ay naglalaman ng mga seksyon na may iba’t ibang uri ng mga setting: mga text field, switch, counter — lahat ng halaga ay awtomatikong nai-save sa 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("Profile")) {
                    TextField("Display name", text: $displayName)
                }

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

                Section {
                    Button("I-reset ang mga setting") {
                        UserDefaults.standard.removePersistentDomain(
                            forName: Bundle.main.bundleIdentifier!)
                    }
                    .tint(.red)
                }
            }
            .navigationTitle("Settings")
        }
    }
}

Ang form ay naglalaman ng apat na @AppStorage na property ng iba’t ibang uri: String para sa pangalan, Bool para sa mga notification, Int para sa bilang ng mga resulta at String para sa napiling tab. Ang lahat ng kontrol ay konektado sa mga property sa pamamagitan ng Binding ($displayName, $notificationsEnabled atbp.). Ang button na “Reset settings” ay nagre-reset ng lahat ng UserDefaults, binubura ang domain ng application — pagkatapos nito, awtomatikong babalik ang @AppStorage sa mga default na halaga.

Pag-sync ng @AppStorage sa 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 = "blue"

    var body: some View {
        Form {
            Picker("Widget theme", selection: $widgetTheme) {
                Text("System").tag("system")
                Text("Light").tag("light")
                Text("Dark").tag("dark")
            }
            Picker("Accent color", selection: $widgetColor) {
                Text("Blue").tag("blue")
                Text("Green").tag("green")
                Text("Red").tag("red")
            }
        }
    }
}

Para sa App Group (shared storage sa pagitan ng application at extensions) ang @AppStorage ay tumatanggap ng parameter na store: UserDefaults(suiteName:). Ang mga halaga ay nai-save sa isang shared container na accessible sa pangunahing application, Widget, Watch App at iba pang extension ng parehong grupo. Maaaring basahin ng Widget ang mga setting na ito, at sa pagbabago sa application, ang Widget ay awtomatikong nag-a-update sa pamamagitan ng mekanismo ng pagmamasid ng UserDefaults.

Mga Madalas Itanong

Ano ang pagkakaiba sa pagitan ng @AppStorage at @State?

Ang @State ay nag-iimbak ng halaga lamang sa memory at nire-reset kapag ni-restart ang application. Ang @AppStorage ay nagse-save ng halaga sa UserDefaults at ibinabalik ito sa susunod na pagtakbo. Gamitin ang @State para sa pansamantalang data ng screen, @AppStorage — para sa mga setting na dapat tumagal sa restart.

Maaari bang gamitin ang @AppStorage sa Enum?

Oo, kung ang Enum ay nagpapatupad ng RawRepresentable protocol na may rawValue na uri ng String o Int. Halimbawa: @AppStorage("theme") var theme: AppTheme = .system. Awtomatikong sine-serialize ng SwiftUI ang enum sa pamamagitan ng rawValue at ibinabalik ito kapag na-load.

Paano linisin ang lahat ng @AppStorage na halaga?

Tawagan ang UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) para sa standard storage o removeObject(forKey:) para sa partikular na key. Pagkatapos ng paglilinis, lahat ng @AppStorage property ay babalik sa mga default na halaga na tinukoy sa deklarasyon.

Gumagana ba ang @AppStorage sa App Extensions?

Oo, para sa synchronisation sa pagitan ng application at extensions gamitin ang App Group: @AppStorage("key", store: UserDefaults(suiteName: "group.com.example.app")!). Ang Widget, Share Extension at Watch App ay maaaring magbasa at magsulat sa parehong UserDefaults, at ang mga pagbabago ay awtomatikong sinusubaybayan.

Gaano karaming data ang maiimbak sa @AppStorage?

Ang @AppStorage ay gumagamit ng UserDefaults, na idinisenyo para sa maliit na dami ng data: mga setting, token, counter. Ang inirerekomendang limitasyon — hanggang 100 KB bawat application. Para sa nakaayos o malalaking data (array ng mga bagay, media file) gamitin ang SwiftData, Core Data o file system.

Buod

  • @AppStorage — property wrapper para sa reaktibong pag-iimbak ng mga setting sa UserDefaults
  • Awtomatikong pag-save at awtomatikong pag-update ng UI kapag nagbago ang halaga mula sa anumang pinagmulan
  • Sinusuportahan ang String, Int, Double, Bool, Data, URL at RawRepresentable enums
  • Default na halaga ay itinakda sa deklarasyon at ibinabalik sa unang pagtakbo
  • App Group ay nagpapahintulot sa pag-sync ng @AppStorage sa pagitan ng application at extensions
  • UserDefaults ay angkop lamang para sa maliit na dami ng data — hanggang 100 KB
  • Gamitin ang @AppStorage para sa mga setting ng user, @State — para sa pansamantalang estado ng screen

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din