I am using the Observable macro and when I use @Environment property wrapper to instance my model the preview stop working. Sample code below
import SwiftUI
import Observation
@Observable class Library {
// ...
}
Now in my main app I created an instance of Library and add that instance to the environment
@main
struct BookReaderApp: App {
@State private var library = Library()
var body: some Scene {
WindowGroup {
LibraryView()
.environment(library)
}
}
}
Now if I want to retrieve the Library instance from any view using the @Environment property wrapper the preview stop working completely (Assume the BoolView actually exist)
struct LibraryView: View {
@Environment(Library.self) private var library
var body: some View {
List(library.books) { book in
BookView(book: book)
}
}
}
#Preview {
LibraryView()
}
If I go back and don’t use the Observable macro and just use the ObservableObject with @StateObject, .environemntObject and @EnvironmentObject the #Preview work fine.
This Observable macro is "related" new.
Any idea why this is happening? Is there any workaround? I am working with Xcode Version 15.2. Thanks in advance for any kind of help!
>Solution :
I’ve found out why. When you use the new Observation framework you need to declare this struct along with its extension (usually calling it ClassNameKey) this way:
private struct LibraryKey: EnvironmentKey {
static var defaultValue: Library = Library()
}
extension EnvironmentValues {
var library: Library {
get { self[LibraryKey.self] }
set { self[LibraryKey.self] = newValue }
}
}
Then in your App struct you inject it using the path to it like this:
@main
struct BookReaderApp: App {
@State private var library = Library()
var body: some Scene {
WindowGroup {
LibraryView()
.environment(\.library, library) // <-- Do it this way, using the path
}
}
}
And in any view you want to use your dependency you call it the same way, using the path: @Environment(\.library) private var library.
As for the previews, the dependency need to be injected this way:
#Preview {
ContentView()
.environment(\.library, Library())
}
If you want to know more go here: Observation Framework
Tell me if that worked for you!