Swiftui - How do I initialize an observedObject using an environmentobject as a parameter?

10,007

Here is the approach (the simplest IMO):

struct MyCoolView: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        MyCoolInternalView(ViewObject(id: self.userData.UID))
    }
}

struct MyCoolInternalView: View {
    @EnvironmentObject var userData: UserData
    @ObservedObject var viewObject: ViewObject

    init(_ viewObject: ViewObject) {
        self.viewObject = viewObject
    }

    var body: some View {
            Text("\(self.viewObject.myCoolProperty)")
    }
}
Share:
10,007
snarik
Author by

snarik

Updated on June 05, 2022

Comments

  • snarik
    snarik almost 2 years

    I'm not sure if this is an antipattern in this brave new SwiftUI world we live in, but essentially I have an @EnvironmentObject with some basic user information saved in it that my views can call.

    I also have an @ObservedObject that owns some data required for this view.

    When the view appears, I want to use that @EnvironmentObject to initialize the @ObservedObject:

    struct MyCoolView: View { 
    
        @EnvironmentObject userData: UserData
        @ObservedObject var viewObject: ViewObject = ViewObject(id: self.userData.UID)  
    
        var body: some View { 
                Text("\(self.viewObject.myCoolProperty)")
        } 
    }
    

    Unfortunately I can't call self on the environment variable until after initialization:

    "Cannot use instance member 'userData' within property initializer; property initializers run before 'self' is available."

    I can see a few possible routes forward, but they all feel like hacks. How should I approach this?

  • snarik
    snarik over 4 years
    This is perfect. The MyCoolView was actually a child to a 'home' view where I declared the ObservedObject. Thanks!
  • BobiSad
    BobiSad over 4 years
    But what if you want to manipulate the userData inside ViewObject without an entirely new ViewObject being created every time?