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 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.
import SwiftUIstruct 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!
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.
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!
@AppStorage: Use for global user settings, high scores, login tokens, or permanent preferences.@SceneStorage: Use for temporary UI state, like remembering which tab is selected or the text in an unfinished draft.Which property wrapper should you use to permanently save a user's notification preferences across app launches?