Accessing an environmentObject's function in another environmentObject which is created at the same time

Hello guys!

I have the following problem:

In my Main SwiftUI file (the one who calls the ContentView). I have 5 StateObjects which are all passed to the environment.

3 of them are DataModels which i always want to have access to, 1 is a Sheet Manager who have the information which sheet has to be shown or not and the other one is a Manager Class which has to collect the informations in the App to create a PDF from it afterwards.

import Firebase

@main
struct BillApp: App {
  @StateObject var billModel = BillModel()
  @StateObject var customerModel = CustomerModel()
  @StateObject var itemModel = ItemModel()
  @StateObject var sheet = Sheet()
  @StateObject var manager : PDFManager = PDFManager()

  init() {
    FirebaseApp.configure()
  }
     
   
  var body: some Scene {
    WindowGroup {
      MainView()
        .environmentObject(billModel)
        .environmentObject(customerModel)
        .environmentObject(itemModel)
        .environmentObject(sheet)
        .environmentObject(manager)
        .onAppear(perform: {
          billModel.getData()
          customerModel.getData()
          itemModel.getData()
        })
    }
  }
}

My problem is, that in my PDFManager i need the billModel which was put in the environment at the same time, because this model has the function to save the bill to the Firebase DB.

class PDFManager: ObservableObject {
  @EnvironmentObject var billModel : BillModel

   func saveToDB() {
    billModel.addData(billToAdd: bill)
  }

When I try to call the functions from the billModel I get the following error:

Thread 1: Fatal error: No ObservableObject of type BillModel found. A View.environmentObject(_:) for BillModel may be missing as an ancestor of this view.

Do you guys have any ideas how i could fix this and have the PDFManager still created on the same place and have it in the environment? I have to access it in a lot of files.

I would appreciate your help so much, thank in advance!!

I'm not sure, if it is intended by Apple or even allowed to use @EnvironmentObject inside the model code. I think you should declare billModel in PDFManger as a simple let or var and set it yourself using an initializer:

Hello Dirk, thanks for your answer!

The problem is, that is dont only need the billModel in the PDFManger but also everywhere else in the App because it contains the list with all entries from the DB.

The PDFManager Class is no DataModel but a helper class that collects informations and provides functions for creating a pdf out of the collected informations.

The problem is, that is dont only need the billModel in the PDFManger but also everywhere else in the App

I do not think that would be an issue, you can do what Dirk-FU said:

class PDFManager: ObservableObject {
    var billModel : BillModel?
    
    func saveToDB() {
        billModel?.addData(billToAdd: bill)
    }
    
    //...
    
}

And set PDFManager.billModel on start up of your app:

    var body: some Scene {
        WindowGroup {
            MainView()
                .environmentObject(billModel)
                .environmentObject(customerModel)
                .environmentObject(itemModel)
                .environmentObject(sheet)
                .environmentObject(manager)
                .onAppear(perform: {
                    manager.billModel = billModel
                    billModel.getData()
                    customerModel.getData()
                    itemModel.getData()
                })
        }
    }
Accessing an environmentObject's function in another environmentObject which is created at the same time
 
 
Q