Skip to content

Instantly share code, notes, and snippets.

@drekka
Last active October 23, 2023 20:15
Show Gist options
  • Save drekka/17c38ec226cb819312580719651163e5 to your computer and use it in GitHub Desktop.
Save drekka/17c38ec226cb819312580719651163e5 to your computer and use it in GitHub Desktop.
A wrapper for SwiftUI @AppStorage that also provides a Publisher for non-View types to receive updates.
/// Property wrapper that acts the same as @AppStorage, but also provides a ``Publisher`` so that non-View types
/// can receive value updates.
@propertyWrapper
struct PublishingAppStorage<Value> {
var wrappedValue: Value {
get { storage.wrappedValue }
set {
storage.wrappedValue = newValue
subject.send(storage.wrappedValue)
}
}
var projectedValue: Self {
self
}
/// Provides access to ``AppStorage.projectedValue`` for binding purposes.
var binding: Binding<Value> {
storage.projectedValue
}
/// Provides a ``Publisher`` for non view code to respond to value updates.
private let subject = PassthroughSubject<Value, Never>()
var publisher: AnyPublisher<Value, Never> {
subject.eraseToAnyPublisher()
}
private var storage: AppStorage<Value>
init(wrappedValue: Value, _ key: String) where Value == String {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value: RawRepresentable, Value.RawValue == Int {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value == Data {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value == Int {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value: RawRepresentable, Value.RawValue == String {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value == URL {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value == Double {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
init(wrappedValue: Value, _ key: String) where Value == Bool {
storage = AppStorage(wrappedValue: wrappedValue, key)
}
mutating func update() {
storage.update()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment