Design Converter
Education
Last updated on Jan 21, 2025
Last updated on Dec 13, 2024
When developing apps in SwiftUI, maintaining state across scenes is a common challenge. Enter the @SceneStorage property wrapper, a lightweight and efficient solution for automatic state restoration.
This article will explore how the SwiftUI SceneStorage property wrapper simplifies state management, how scene storage works, and its best practices for handling sensitive data.
The @SceneStorage is a property wrapper designed to persist lightweight data specific to the same scene in a SwiftUI app. It leverages the system's notion of state persistence to ensure values are automatically saved and restored when a scene transitions or is explicitly destroyed.
Unlike @AppStorage, which persists data across the entire app, @SceneStorage is scoped to a single scene, making it ideal for small amounts of data that do not need to be shared across multiple scenes or user defaults.
Automatic State Restoration: Saves and restores values seamlessly when the scene is recreated.
Scoped to the Same Scene: Ensures data stored applies only to the current scene.
Lightweight: Ideal for small amounts of data like string, int, or model data for UI elements such as a selected tab or scroll view offset.
The system manages @SceneStorage by tying values to the lifecycle of the scene. When a scene is moved to the background or explicitly destroyed, the data stored with @SceneStorage is saved. Later, when the scene is reloaded, the system restores the previously saved values later.
Here’s an example to clarify its functionality:
1struct ContentView: View { 2 @SceneStorage("selectedTab") private var selectedTab: Int = 0 3 4 var body: some View { 5 TabView(selection: $selectedTab) { 6 Text("Home").tabItem { Text("Home") }.tag(0) 7 Text("Profile").tabItem { Text("Profile") }.tag(1) 8 } 9 } 10}
In this example, the selected tab index (selectedTab) is automatically saved when the scene is closed or moved to the background and restored when it reopens.
The @SceneStorage property wrapper is particularly useful for:
• Saving and restoring the current page in multi-page apps.
• Maintaining scroll view positions.
• Persisting UI states like a selected tab in a tab view.
If your app contains a long scroll view, persisting the scroll position across app launches enhances user preferences. Here’s how to implement it:
1struct ContentView: View { 2 @SceneStorage("scrollPosition") private var scrollPosition: Double = 0.0 3 4 var body: some View { 5 ScrollView { 6 VStack { 7 ForEach(0..<100, id: \.self) { index in 8 Text("Item \(index)") 9 } 10 } 11 } 12 .onAppear { 13 // Restore the scroll position 14 scrollToPosition(scrollPosition) 15 } 16 .onDisappear { 17 // Save the current scroll position 18 scrollPosition = getCurrentScrollPosition() 19 } 20 } 21}
This approach ensures a smooth save and restore cycle, creating a better user experience.
Although both are property wrappers, their use cases differ:
Feature | @SceneStorage | @AppStorage |
---|---|---|
Scope | Per Scene Storage | Across the entire app |
Use Case | UI-specific state (e.g., tabs) | Global user preferences |
Persistence Location | Temporary (per scene lifecycle) | User defaults |
Example Key | "selectedTab" | "themePreference" |
Use @SceneStorage when data needs to be tied to the same scene, and @AppStorage for persistent user preferences like theme or layout settings.
While @SceneStorage is convenient, storing sensitive data like passwords or private information is not ideal. Instead, rely on more secure options like the Keychain.
You can use custom types by making them conform to the Codable protocol:
1struct CustomModel: Codable { 2 var name: String 3 var age: Int 4} 5 6struct ContentView: View { 7 @SceneStorage("userData") private var userData: CustomModel = CustomModel(name: "John", age: 30) 8 9 var body: some View { 10 Text("Hello, \(userData.name)!") 11 } 12}
Poor Performance: Avoid using @SceneStorage for large model data.
Explicitly Destroyed Scenes: Ensure your data is properly handled when a scene is destroyed.
The @SceneStorage property wrapper in SwiftUI is a powerful tool for saving and restoring lightweight data tied to a scene's lifecycle. Enabling automatic state restoration ensures a seamless user experience while keeping your code efficient and clean. Whether you're tracking a selected tab, persisting a switcher snapshot, or maintaining a current page, SceneStorage proves invaluable.
You can optimize your app's state management strategy by understanding how scene storage works and combining it with other property wrappers like @AppStorage. Just remember to avoid storing sensitive data and focus on small amounts of lightweight data. With these best practices in place, you’ll unlock the full potential of SwiftUI SceneStorage.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.