SwiftUI AppStorage property wrapper

Last updated 11 October 2021

SwiftUI has a dedicated property wrapper for reading values from UserDefaults, which will automatically re-invoke the view's body property when the value updates. This wrapper effectively listens to a key in UserDefaults, and will refresh the interface if the value for that key changes.

For example, this will listen to UserDefaults for a "isFaceIDEnabled" key, which will be updated when the toggle is switched:

struct ContentView: View {
    @AppStorage("isFaceIDEnabled") private var isFaceIDEnabled: Bool = false

    var body: some View {
        VStack {
            Text("Face ID is \(isFaceIDEnabled ? "enabled" : "disabled").")

            Toggle(isOn: $isFaceIDEnabled) {
                Text("Face ID")
            }
        }
    }
}

Changing isFaceIDEnabled above will cause the new value to be written to UserDefaults immediately, while also updating the view. The same would be true if we had used the older method:

Updating isFaceIDEnabled value above will cause the new value to be written to UserDefaults immediately while also updating the view simultaneously. The same would be true if we use the more old-fashioned approach:

UserDefaults.standard.set(true, forKey: "isFaceIDEnabled")

Important notes

AppStorage saves data to UserDefaults, which is not secure storage. So, you should not store any personal data using AppStorage, because it's relatively easy to extract.