The @FetchRequest property wrapper that ships with SwiftUI helps declaring properties that are auto-updated whenever a Core Data storage changes. You only have to provide a fetch request:
struct MyView: View {
@FetchRequest(fetchRequest: /* some fetch request */)
var myValues: FetchedResults<MyValue>
}
The fetch request can't access the storage without a managed object context. This context has to be passed in the view's environment.
And now I'm quite puzzled.
Is there any public API that allows a property wrapper to access the environment of its enclosing object, or to have SwiftUI give this environment to the property wrapper?
With Xcode 13 (haven't tested on earlier versions) as long as your property wrapper implements DynamicProperty
you can use the @Environment
property wrapper.
The following example create a property wrapper that's read the lineSpacing
from the current environment.
@propertyWrapper
struct LineSpacing: DynamicProperty {
@Environment(\.lineSpacing) var lineSpacing: CGFloat
var wrappedValue: CGFloat {
lineSpacing
}
}
Then you can use it just like any other property wrapper:
struct LineSpacingDisplayView: View {
@LineSpacing private var lineSpacing: CGFloat
var body: some View {
Text("Line spacing: \(lineSpacing)")
}
}
struct ContentView: View {
var body: some View {
VStack {
LineSpacingDisplayView()
LineSpacingDisplayView()
.environment(\.lineSpacing, 99)
}
}
}
This displays:
Line spacing: 0.000000
Line spacing: 99.000000