SwiftUI AppStorage & SceneStorage

SwiftUI AppStorage & SceneStorage

For saving tiny pieces of data, such as a user's preference for Dark Mode or their high score in a game, Core Data and FileManager are overkill.

Historically, Apple developers used a tool called UserDefaults for this lightweight persistence.

SwiftUI wraps this functionality beautifully using two specialized property wrappers: @AppStorage and @SceneStorage.


The @AppStorage Wrapper

The @AppStorage property wrapper reads and writes values directly to UserDefaults.

When the value in UserDefaults changes, your SwiftUI view instantly re-renders!

You simply provide a unique string key, and a default value to use if the key hasn't been saved yet.

Using @AppStorage:

import SwiftUI

struct SettingsView: View { // Look for "isDarkMode" in UserDefaults, default to false @AppStorage("isDarkMode") private var isDarkMode = false var body: some View { VStack { Toggle("Enable Dark Mode", isOn: $isDarkMode) .padding() Text(isDarkMode ? "Dark Theme Active" : "Light Theme Active") } } }

If the user quits the app and reopens it tomorrow, isDarkMode will perfectly remember its last state!


The @SceneStorage Wrapper

While @AppStorage saves data globally across the entire app permanently, @SceneStorage is slightly different.

@SceneStorage is used for State Restoration. It saves data specific to a single window (scene), and the data is destroyed if the user completely force-quits the app.

It is primarily used to remember what the user was currently typing or reading if iOS temporarily suspends the app in the background.

Using @SceneStorage:

struct TextEditorView: View {
    // Remembers the text only while the app is alive/suspended
    @SceneStorage("draftText") private var draftText = ""
    var body: some View {
        TextEditor(text: $draftText)
            .padding()
    }
}

If you are on an iPad with multiple windows of the same app open, each window gets its own separate @SceneStorage draft!


When to use which?


Exercise

Which property wrapper should you use to permanently save a user's notification preferences across app launches?