Last active
May 22, 2021 11:19
-
-
Save mattyoung/ac9bae68cef40fc3bf9469b9b39e0a56 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
public protocol ObservablePropertySource: ObservableObject { | |
static var shared: Self { get } | |
} | |
@propertyWrapper | |
public struct ObservableProperty<S: ObservablePropertySource, T>: DynamicProperty { | |
@ObservedObject private var source: S | |
private let keyPath: KeyPath<S, T> | |
public init(_ keyPath: KeyPath<S, T>) { | |
source = S.shared | |
self.keyPath = keyPath | |
} | |
public var wrappedValue: T { | |
source[keyPath: keyPath] | |
} | |
} | |
public final class Features: ObservablePropertySource { | |
public static let shared = Features() | |
private init() { } | |
@Published public var isDebugMenuEnabled = false | |
} | |
public final class AppSettings: ObservablePropertySource { | |
public static let shared = AppSettings() | |
private init() { } | |
@AppStorage("appSetting1") public var appSetting1: Int = 42 | |
// could just be `static` and access directly without going through @wrapper | |
@AppStorage("appSetting2") public static var appSetting2: String = "Hello" | |
} | |
public final class SceneSettings: ObservableObject { | |
public static let shared = SceneSettings() | |
private init() { } | |
@SceneStorage("sceneValue1") public var sceneSetting1: Int = 54 | |
@SceneStorage("sceneValue2") public var sceneSetting2: String = "World" | |
} | |
struct ContentView: View { | |
// @Feature(\.isDebugMenuEnabled) var showDebugMenu | |
// @AppSetting(\.appSetting1) var appSetting1 | |
@ObservableProperty(\Features.isDebugMenuEnabled) var showDebugMenu | |
@ObservableProperty(\AppSettings.appSetting1) var appSetting1 | |
var body: some View { | |
VStack { | |
Text("Hello, world!") | |
.padding() | |
if showDebugMenu { | |
Text("Debug Menu on") | |
} else { | |
Text("Debug Menu off") | |
} | |
Text("appSetting1 = \(appSetting1)") | |
// directly access static, better? | |
Text("appSetting2 = \(AppSettings.appSetting2)") | |
} | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment