0
struct ContentView {
    @ObservedObject var annotationsVM = AnnotationsVM()
    //I'd like to pass in the ViewModel() declared below into annotationsVM like AnnotationsVM(VModel: Vmodel)
    @ObservedObjects var VModel = ViewModel()

    var body: some View {
        //All the SwiftUI view setup is in here
    }
}

class AnnotationsVM: ObservableObject {
    @ObservedObject var VModel = ViewModel()
    //I'd like to pass in the VModel in content view like: @ObservedObject var VModel: VModel
}

Obviously, I can't pass in the VModel directly upon ContentView creation like I want to because the VModel object hasn't been created yet so it's inaccessible...

Recap: I want to pass in the VModel instance declared in ContentView into the annotationsVM instance (also declare in ContentView)

nickcoding
  • 305
  • 8
  • 35

1 Answers1

1

You can do it in init like this:

struct ContentView {
    @ObservedObject var annotationsVM: AnnotationsVM
    @ObservedObject var vModel: ViewModel

    init() {
        let vm = ViewModel()
        vModel = vm
        annotationsVM = AnnotationsVM(vModel: vm)
    }

    var body: some View {
        //All the SwiftUI view setup is in here
    }
}

class AnnotationsVM: ObservableObject {
    var vModel: ViewModel

    init(vModel: ViewModel) {
        vModel = vModel
    }
}

And you can use @ObservedObject only in View.

Note: it may be better to pass ViewModels in init as parameters to follow the Dependency Injection pattern.

pawello2222
  • 46,897
  • 22
  • 145
  • 209
  • Thank you, I believe this will work...Just to be clear though, the initialization of the AnnotationsVM class should look like init(vModel: ViewModel) { }, right? – nickcoding May 31 '20 at 16:03
  • 1
    Sorry, but the initialization in contentview doesn't work...it says that the vModel you pass into AnnotationsVM has an error 'self used before all stored properties are initialized' – nickcoding May 31 '20 at 16:40
  • 1
    I updated my answer. Now with `let vm = ViewModel()` there should not be any errors of invalid use of `self`. – pawello2222 May 31 '20 at 16:43
  • Is there any other way to pass arguments to ObservableObject? because in each parent view update, the child view initialize again, and state inside ObservableObject will not persist. – user12208004 Oct 24 '20 at 12:29
  • @user12208004 You can use a `@StateObject` in the parent view. See [What is the difference between ObservedObject and StateObject in SwiftUI](https://stackoverflow.com/q/62544115/8697793) – pawello2222 Oct 24 '20 at 12:41
  • @pawello2222 thanks, I understand `@StateObject`, but is there any way to initialize `@StateObject` with an argument? – user12208004 Oct 24 '20 at 12:59
  • @user12208004 See [Initialize StateObject with a parameter in SwiftUI](https://stackoverflow.com/q/62635914/8697793) – pawello2222 Oct 24 '20 at 16:29
  • @pawello2222, I thought you may know the different way other than the answers on the above link because none of these answers solve its question. Anyway thanks for your kind help! – user12208004 Oct 28 '20 at 09:52