SwiftUI AppStorage & SceneStorage
SwiftUI AppStorage & SceneStorage
Persist small values with @AppStorage and view-state per scene with @SceneStorage.
@AppStorage (User Defaults)
Bind a value directly to UserDefaults so changes persist across app launches.
Syntax: @AppStorage("key") var value: T = default
Example
import SwiftUI
struct AppStorageDemo: View {
@AppStorage("username") private var username = ""
var body: some View {
VStack(spacing: 12) {
Text("Hello, \(username.isEmpty ? "Guest" : username)")
TextField("Username", text: $username)
.textFieldStyle(.roundedBorder)
}
.padding()
}
}
import SwiftUI
struct ContentView: View {
var body: some View { AppStorageDemo() }
}
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup { ContentView() }
}
}
This example stores the username in UserDefaults and keeps the UI in sync.
@SceneStorage (Per-Scene UI State)
Preserve transient UI data (like a draft) per window/scene; state is restored when the scene returns.
Syntax: @SceneStorage("key") var value: T
Example
import SwiftUI
struct SceneStorageDemo: View {
@SceneStorage("draft_note") private var draft = ""
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("Draft:")
TextEditor(text: $draft)
.frame(minHeight: 120)
.overlay(RoundedRectangle(cornerRadius: 6).stroke(.secondary))
}
.padding()
}
}
import SwiftUI
struct ContentView: View {
var body: some View { SceneStorageDemo() }
}
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup { ContentView() }
}
}
This example keeps a text draft per scene so switching windows preserves the content independently.
Tip: Use @AppStorage for preferences and @SceneStorage for transient UI state.