SwiftUI - Accessing StateObject's Object Without Being Installed on a View

I have a core data program. I run my fetch request in a class i.e. a view model and assign it to a StateObject in the ContentView. When I attempt to use the fetch request results from the view model in a selected view, the DataTable, I get this message: Accessing StateObject's object without being installed on a View. This will create a new instance each time. Not sure what to do. Below is my code:

struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @State var selection: DataDisplayed? = nil
    @StateObject var dataViewModel: FetchCoreData = FetchCoreData()
    var body: some View {
        NavigationSplitView{
            sidebarContent
                .navigationSplitViewColumnWidth(min: 200, ideal: 200, max: 200)
        } detail: {
            detailContent
        }
        .navigationSplitViewStyle(.balanced)
        .navigationTitle("Testing")
        .frame(width: 1000, height: 800)

    }
} 
extension ContentView {
    @ViewBuilder
    var detailContent: some View {
        if let selection = selection {
            detailContent(for: selection)
                .buttonStyle(.bordered)
        } else {
            Text("Make A Selection")
        }
    }
    @ViewBuilder
    func detailContent(for screen: DataDisplayed) -> some View {
        switch screen {
        case .VOODT: DataTable(dataModel: dataViewModel.fetchRequest)
        case .NWDT: Text("Start")
        case .VOOG1: Text("VOO Graph 1 Year")
        default: Text("Not yet implemented")
        }
    }
}
class FetchCoreData: ObservableObject {
    
    @FetchRequest var fetchRequest: FetchedResults<TradingDayPrices>
    init() {
        _fetchRequest = FetchRequest<TradingDayPrices>(sortDescriptors: [NSSortDescriptor(key: "timeStamp", ascending: true)], predicate: NSPredicate(format: "net > %d", 0.0))
    }
}
struct DataTable: View {
    var dataModel: FetchedResults<TradingDayPrices>
    init(dataModel: FetchedResults<TradingDayPrices>) {
        self.dataModel = dataModel
    }
    var body: some View {. // fails on this line ########################
        List(dataModel.fetchRequest, id: \.self) { item in
            Text("\(dateToStringFormatter.string(from: item.timeStamp!))  -  ") +
            Text("\(item.vooClose) ")
        }
    }
}
Answered by ChrisMH in 751652022

Thank you MobileTen. I needed to use async and await. Below are the main call, view model and data table structure that work.

@main
struct NavigationStackApp: App {
    let coreDataManager = CoreDataManager()
    var body: some Scene {
        WindowGroup {
            ContentView(fetchedCoreData: FetchCoreData(persistentContainer: coreDataManager.persistentContainer))
        }
    }
}
class FetchCoreData: ObservableObject {
    @Published var closingValues: [TradingDayPrices] = []
    private (set) var persistentContainer: NSPersistentContainer
    init(persistentContainer: NSPersistentContainer) {
        self.persistentContainer = persistentContainer
        Task {
            closingValues = await FetchResults(moc: persistentContainer.viewContext)
        }
    }
}
func FetchResults(moc: NSManagedObjectContext) async -> [TradingDayPrices] {
    var coreDataValues: [TradingDayPrices] = []
    let fetchRequest : NSFetchRequest<TradingDayPrices> = TradingDayPrices.fetchRequest()
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: true)]
    fetchRequest.predicate = NSPredicate(format: "netWorth > %d", 0.0)
    do {
        coreDataValues = try moc.fetch(fetchRequest)
    } catch let error {
        print("Error fetching max date. \(error.localizedDescription)")
    }
    return coreDataValues
}
struct DataTable: View {
    var closingValues: [TradingDayPrices] = []
    init(closingValues: [TradingDayPrices]) {
        self.closingValues = closingValues
    }
    var body: some View {
        List(closingValues, id: \.self) { item in
            Text("\(dateToStringFormatter.string(from: item.timeStamp!))  -  ") +
            Text("\(item.vooClose) ")
        }
    }
}
Accepted Answer

Thank you MobileTen. I needed to use async and await. Below are the main call, view model and data table structure that work.

@main
struct NavigationStackApp: App {
    let coreDataManager = CoreDataManager()
    var body: some Scene {
        WindowGroup {
            ContentView(fetchedCoreData: FetchCoreData(persistentContainer: coreDataManager.persistentContainer))
        }
    }
}
class FetchCoreData: ObservableObject {
    @Published var closingValues: [TradingDayPrices] = []
    private (set) var persistentContainer: NSPersistentContainer
    init(persistentContainer: NSPersistentContainer) {
        self.persistentContainer = persistentContainer
        Task {
            closingValues = await FetchResults(moc: persistentContainer.viewContext)
        }
    }
}
func FetchResults(moc: NSManagedObjectContext) async -> [TradingDayPrices] {
    var coreDataValues: [TradingDayPrices] = []
    let fetchRequest : NSFetchRequest<TradingDayPrices> = TradingDayPrices.fetchRequest()
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: true)]
    fetchRequest.predicate = NSPredicate(format: "netWorth > %d", 0.0)
    do {
        coreDataValues = try moc.fetch(fetchRequest)
    } catch let error {
        print("Error fetching max date. \(error.localizedDescription)")
    }
    return coreDataValues
}
struct DataTable: View {
    var closingValues: [TradingDayPrices] = []
    init(closingValues: [TradingDayPrices]) {
        self.closingValues = closingValues
    }
    var body: some View {
        List(closingValues, id: \.self) { item in
            Text("\(dateToStringFormatter.string(from: item.timeStamp!))  -  ") +
            Text("\(item.vooClose) ")
        }
    }
}
SwiftUI - Accessing StateObject's Object Without Being Installed on a View
 
 
Q