ilvthsgm
ilvthsgm

Reputation: 636

Multiple Instance of the Same EnvironmentObject

I have a @EnvironmentObject.

@main
struct Image_WidgetApp: App {
    @State var imageNumString = ""
    @State var showDetailView = false  
    @EnvironmentObject var userData: UserData
    var body: some Scene {        
        WindowGroup {
            if(!showDetailView){
                ContentView()
                    .onOpenURL { url in
                        imageNumString = url.absoluteString
                        showDetailView = true
                    }
                    .environmentObject(UserData())   // First instance of the environmentObject
            }
            else{
                ImageDetailView( mySubstring: $imageNumString, doneFunction: {
                    self.showDetailView = false
                })                                    
                .environmentObject(UserData())   // Second instance of the environmentObject
            }
        }
    }
}

If user open the app via the app icon, I set ContentView() active.

If user open the app via the widget, I set ImageDetailView() active by setting the showDetailView = true in onOpenURL.

Everything is okay until now.

The problem is possibly I have 2 different instance of the same environmentObject. See https://github.com/peterfriese/Swift-EnvironmentObject-Demo

Because when I change anything in any view, the other view doesn't aware of it.

To get rid of the problem, I have tried to use NavigationLink, since this approach aims to push the ImageDetailView() as a child view but no chance. Widget click doesn't push the ImageDetailView() to the navigation stack.

@main
struct Image_WidgetApp: App {
    @State var imageNumString = ""
    @State var showDetailView = false  
    @EnvironmentObject var userData: UserData
    var body: some Scene {        
        WindowGroup {
                ContentView()
                    .onOpenURL { url in
                        imageNumString = url.absoluteString
                        showDetailView = true
                        if imageNumString.count > 0{

                            imageNumString = url.absoluteString
            
                            NavigationLink(destination: ImageDetailView(mySubstring: $imageNumString), isActive: $showDetailView) {
                                EmptyView()
                            } .hidden()
                        }
                        .environmentObject(UserData())  
            }
        }
    }     
}

How can I use the @EnvironmentObject as a single instance?

Upvotes: 1

Views: 332

Answers (1)

pawello2222
pawello2222

Reputation: 54426

How can I use the @EnvironmentObject as a single instance?

You can create one global UserData instance and inject where necessary:

@main
struct Image_WidgetApp: App { 
    @StateObject var userData = UserData()

    var body: some Scene {        
        WindowGroup {
                FirstView()
                    .environmentObject(userData)
                SecondView()
                    .environmentObject(userData)
            }
        }
    }     
}

Regarding launching a different view from an App/Widget see:

Upvotes: 3

Related Questions