SwiftUI SceneStorage property wrapper

Last updated 21 October 2021

SwiftUI's SceneStorage property wrapper allows us to save unique data for each screen. SceneStorage works similar to AppStorage. It lets you provide it with a name to store data and a default value. However, instead of working with UserDefaults, it gets used for state restoration. It even works really well with complex multi-scene apps, which we often see in iPadOS.

For example, if you are building a note-taking app and want to keep what the user was typing, you can utilise SceneStorage to do the thing:

struct ContentView: View {
    @SceneStorage("notes") private var notes: String = ""

    var body: some View {
        NavigationView {
            TextEditor(text: $notes)
        }
        .navigationViewStyle(.stack)
    }
}

The above example is using .stack to force iPad to allocate all the space to the text editor. If you're using Xcode 12, you need to use StackNavigationViewStyle to achieve the same outcome.

SceneStorage will make sure that each scene has its own copy of the text. If you run the app side by side, both of them will save and restore their data correctly.

Notes:

  • Do not save huge data, only save data needed for state restoration.
  • Do not store sensitive data because SceneStorage is not a secure storage.
  • If user terminates/destroys the app, the storage is also destroyed.