Using an @EnvironmentObject Breaks Xcode Previews

macOS 12.1, Xcode 13.2.1

I'm using an ObserveableObject to store all of my settings data for my macOS app. My issue is that while using an EnvironmentObject setup works great for easy access to my settings and view updating, Xcode fails to generate previews when they're in use.

I've tested this with the following code which works just fine:

@ObservedObject var settingsData: SettingsData = SettingsData()

//@EnvironmentObject var settingsData: SettingsData

and then this code, which doesn't generate a preview:

//@ObservedObject var settingsData: SettingsData = SettingsData()

@EnvironmentObject var settingsData: SettingsData

The error Xcode provides is the following:

MessageSendFailure: Message send failure for send previewInstances message to agent

==================================

|  MessageError: Connection interrupted

I can provide more of my code if needed but I wasn't sure if any of it had to do with this or if this is just an Xcode issue.

Answered by thafner in 700412022

I would recommend trying to put the .environmentObject modifier on the view that you're previewing or the top level group if there are two or more of them. In the modifier you'll have to specify an instance of your environment object. Based on your code sample, you could probably just put SettingsData() in the argument for the modifier to satisfy it.

Here's an example of the preview code that might fit your needs (one view)

static var previews: some View {

SomeView()
.environmentObject(SettingsData())

}

or more than one view

static var previews: some View {

Group {

SomeView()

AnotherView()

// Any other views that would be placed here

}
.environmentObject(SettingsData())

}

Are you making sure to satisfy the @EnvironmentObject requirement also for your PreviewProviders?

Accepted Answer

I would recommend trying to put the .environmentObject modifier on the view that you're previewing or the top level group if there are two or more of them. In the modifier you'll have to specify an instance of your environment object. Based on your code sample, you could probably just put SettingsData() in the argument for the modifier to satisfy it.

Here's an example of the preview code that might fit your needs (one view)

static var previews: some View {

SomeView()
.environmentObject(SettingsData())

}

or more than one view

static var previews: some View {

Group {

SomeView()

AnotherView()

// Any other views that would be placed here

}
.environmentObject(SettingsData())

}
Using an @EnvironmentObject Breaks Xcode Previews
 
 
Q