I'm facing the same issue with a custom property wrapper I created to manage in-app settings (like user's preferred color scheme regardless the system's scheme), the struct im having is this:
import SwiftUI
class SettingKeys: ObservableObject {
@AppStorage("colorScheme") var colorScheme: AppColorScheme?
}
@propertyWrapper
struct AppSetting<T>: DynamicProperty {
@StateObject private var keys = SettingKeys()
private let key: ReferenceWritableKeyPath<SettingKeys, T>
var wrappedValue: T {
get {
keys[keyPath: key]
}
nonmutating set {
keys[keyPath: key] = newValue
}
}
var projectedValue: Binding<T> {
.init (
get: { wrappedValue },
set: { wrappedValue = $0 }
)
}
init(_ key: ReferenceWritableKeyPath<SettingKeys, T>) {
self.key = key
}
}
enum AppColorScheme: String {
case light
case dark
var value: ColorScheme {
switch self {
case .light:
return .light
case .dark:
return .dark
}
}
}
When I try to access any settings value from outside a View (like in an extension or helper function) like this:
func someFunc() {
@AppSetting(\.colorScheme) var colorScheme
//do something with colorScheme var
}
i get this runtime error at the getter line: keys[keyPath: key]
:
Accessing StateObject's object without being installed on a View. This will create a new instance each time.
I understand what does this mean, but my use-case requires to access this setting outside of a view, and at the same time I need to use this setting as a wrapper to manager reading and writing its value in a SwiftUI view, something like this:
@AppSetting(\.colorScheme) private var colorScheme
if anybody comes with a best practice it would be appreciated.