onmyway133 / blog

🍁 What you don't know is what you haven't learned
https://onmyway133.com/
MIT License
669 stars 33 forks source link

How to create UserDefaults property wrapper in Swift #926

Open onmyway133 opened 1 year ago

onmyway133 commented 1 year ago

Like AppStorage, we can make a custom UserDefaults property wrapper that conforms to DynamicProperty

@propertyWrapper
public struct UserDefault<Value>: DynamicProperty {
    @State private var value: Value

    let key: String
    let store: UserDefaults

    public init(
        wrappedValue: Value,
        _ key: String,
        store: UserDefaults = .standard
    ) {
        self.key = key
        self.store = store

        let value = (store.object(forKey: key) as? Value) ?? wrappedValue
        self._value = State(wrappedValue: value)
    }

    public var wrappedValue: Value {
        get {
            value
        }

        nonmutating set {
            store.set(newValue, forKey: key)
            value = newValue
        }
    }

    public var projectedValue: Binding<Value> {
        .init(
            get: { wrappedValue },
            set: { wrappedValue = $0 }
        )
    }
}