UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Environment Variables in Previews

Forums > SwiftUI

The following lines of code are added to the SceneDelegate class - in the appropriate places - ie: missions is declared as a new property of the class; the missions parameter is amended to the contentView property assignment in the scene method; and the window.rootViewController assignment within the scene method is modified with the missions environmentObject to place the data into the app environment.

let missions = MissionList()

  let contentView = ContentView(missions: missions)

    window.rootViewController = UIHostingController(rootView: contentView.environmentObject(missions))

In ContentView, the @ObservedObject property wrapper is used to declare ownership of the missions data of type MissionList. Elsewhere in other views, the same property is wrapped with EnvironmentObject in order to use it. That all works lovely jubly.

However, the compiler makes a complaint when I add an @EnvironmentObject wrapper for the preview to use the same data. The error is “Instance member ‘missions’ cannot be used on type ‘ContentView_Previews’.

struct ContentView_Previews: PreviewProvider {

    @EnvironmentObject var missions: MissionList

    static var previews: some View {
        ContentView(missions: missions)
    }
}

In what would appear counterintuitive, when a static let is assigned to be an instance of MissionList, Swift is happy again. A plain let will also produce the same error, so the static key word is doing all of the magic here.

struct ContentView_Previews: PreviewProvider {
    static let missions = MissionList()

    static var previews: some View {
        ContentView(missions: missions)
    }
}

Is this a conformance issue, ie View conformance is different to PreviewProvider conformance? I really would like to understand why this is happening and whether I am even thinking about these concepts properly. Any input would be useful and I am also happy to supply more code if necessary.

3      

I don't have an answer for you but came across your post with the same problem. To solve it, I changed all the instances of the object I want to use app-wide to singletons, but since this app is a SwiftUI learning exercise, I decided to change them back to to @EnvironmentObject and figure out the problem. In my case it won't let me use the obect on an instance of a view referenced within a nested class.

3      

My experience is that I have to create all needed variables in the preview itself. I was never able to use Environment variables or any other local variables of the real view.

3      

@EnvironmentObject only works within a View struct, passing along the object from its ancestor View. Previews don't have an ancestor View so there is no inherited environment to work with.

And I don't think @EnvironmentObject is what you even want here in the first place. You can just do this:

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(missions: MissionList())
    }
}

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.