A Swift Macro that automatically applies @AppStorage to properties, simplifying UserDefaults persistence in SwiftUI.
- Automatically generates
@AppStorageattributes for stored properties - Supports optional types without explicit initializers (
var name: String?) - Customizable key prefix and UserDefaults suite name
- Supports both
structandclasstypes - Opt-out mechanism with
@nonstorage - Skips computed properties,
private/fileprivateproperties automatically
- Swift 5.9+
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
Add the following to your Package.swift:
dependencies: [
.package(url: "https://github.com/LZhenHong/StorageMacro.git", from: "0.0.3")
]Or in Xcode: File > Add Package Dependencies... and enter the repository URL.
import Storage
@storage
struct Settings {
var isDarkMode = false
var fontSize = 14
var username = "Guest"
}This expands to:
struct Settings {
@AppStorage("io.lzhlovesjyq.settings.isdarkmode", store: (UserDefaults(suiteName: "io.lzhlovesjyq.userdefaults") ?? .standard))
var isDarkMode = false
@AppStorage("io.lzhlovesjyq.settings.fontsize", store: (UserDefaults(suiteName: "io.lzhlovesjyq.userdefaults") ?? .standard))
var fontSize = 14
@AppStorage("io.lzhlovesjyq.settings.username", store: (UserDefaults(suiteName: "io.lzhlovesjyq.userdefaults") ?? .standard))
var username = "Guest"
}@storage(prefix: "com.myapp", suiteName: "com.myapp.defaults")
struct Settings {
var isDarkMode = false
}Use @nonstorage to exclude specific properties:
@storage
struct Settings {
var persistedValue = true
@nonstorage
var temporaryValue = false // Won't have @AppStorage applied
}The macro automatically skips:
letconstantsprivateorfileprivateproperties- Computed properties
- Properties without default values (except optional types)
- Properties already marked with
@AppStorage
@storage
struct Settings {
var stored = true // ✅ Gets @AppStorage
var name: String? // ✅ Gets @AppStorage (optional type)
let constant = "value" // ⏭️ Skipped (constant)
private var secret = "" // ⏭️ Skipped (private)
var computed: Int { 42 } // ⏭️ Skipped (computed)
var noDefault: String // ⏭️ Skipped (no default value, non-optional)
}| Parameter | Type | Default | Description |
|---|---|---|---|
prefix |
String |
"io.lzhlovesjyq" |
Key prefix for AppStorage |
suiteName |
String |
"io.lzhlovesjyq.userdefaults" |
UserDefaults suite name |
Marker attribute to exclude a property from automatic @AppStorage generation.
This project is licensed under the MIT License - see the LICENSE file for details.