简体   繁体   中英

How to correctly handle @EnvironmentObject within secondary Class

When using @EnvironmentObject, can you have an @EnvironmentObject inside of another class?

I have a setup (MeetingStats) class and then a processing class(Meeting). The processing class and the setup classes are both displayed via different tabs in my app. So if you can change the settings in setup, you should see in real time the changes to the processing class (that is mostly timer driven).

I have tried to switch from using the AppDelegate to passing things between views, to using @EnvironmentObject. I have changed my ScceneDelegate to create the initial objects, and am passing them.envrionmentObjects to the ContentView. However, when I run the app, the first time I try to access the setup class in the processing class, I crash with the message No ObservableObject of type MeetingStats found. A View.environmentObject(_:) for MeetingStats may be missing as an ancestor of this view.

SceneDelegate

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var meetingStats = MeetingStats()
    var meeting = Meeting()
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
    {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            // passing EnvironmentObjects 
            window.rootViewController = UIHostingController(rootView:
                                                                ContentView()
                                                                .environmentObject(meeting)
                                                                .environmentObject(meetingStats)
                                                             )
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}

Content View is a set of tabs, one for meeting, one for setup and one for statistics

meeting.swift - grossly simplified to show the problem area

//
//  meeting.swift
import Foundation
import SwiftUI
import Combine
import Intents
import os
class Meeting: ObservableObject {
    @EnvironmentObject var meetingStats: MeetingStats
    @objc func calcQuorumEvents() {
   // LOTS of calcualtions     
        self.meetingStats.totalWasteAmount = totalWasteAmount. // HERE's the Crash
        self.meetingStats.totalWasteAmountPersonal = totalWasteAmountPersonal
        self.meetingStats.totalLifetimeWasteAmount = totalLifetimeWasteAmount
    }
  }

Is the issue I am not passing explicitly passing the values to the tabs from the contentView? I have tried explicitly passing the Environment object to the meetingView but still receive the same error:

iOSMeetingView()
                .environmentObject(meeting)
                .environmentObject(meetingStats)
                .tabItem {
                    Image("presentation")
                    Text("Meeting")
            }.tag(1)

I didn't think that was required as Swift was to look in the object hierarchy to find the object.

Did you add the environment objects in view iOSMeetingView?

@EnvironmentObject var meetingStats: MeetingStats

Edited: I am not sure about your requirement. Here is my thought. Pass EnvironmentObject meetingStats only to view and you will get the value changes of meetingStats while updating in Meeting.

class Meeting {
   func calcQuorumEvents(meetingStats: MeetingStats) {
      meetingStats.totalWasteAmount = 12 // HERE's the Crash
      meetingStats.totalWasteAmountPersonal = 60
      meetingStats.totalLifetimeWasteAmount = 8
  }
}

class MeetingStats: ObservableObject  {
    @Published var totalWasteAmount: Int
    @Published var totalWasteAmountPersonal: Int
    @Published var totalLifetimeWasteAmount: Int
    
    init() {
        totalWasteAmount = 0
        totalWasteAmountPersonal = 0
        totalLifetimeWasteAmount = 0
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM