Hi Everyone,
I'm trying to refactor a function to make less future errors in my code. I think I'm doing it the right way, but I keep coming across this error, "No ObservableObject of type PublishedClassAccount found. A View.environmentObject(_:) for PublishedClassAccount may be missing as an ancestor of this view."
I will put my code below, but please let me know if I've missed anything. I keep reading online that it has something to do with needing to add an EnvironmentObject, but I can't make sense of it past that. I've been trying to refactor this for weeks and still not getting anywhere. Once I've learned this I'll apply this refactor to other views that will need it.
Any help here is greatly appreciated! Thank you!
This is the class that I'm trying to refactor to. I've added all of the objects to it that needed to be. Error happens on the line that reads, "newAccount.accountCompanyName = publishedClassAccount.accountCompanyNamePublished":
import SwiftUI
class funcTest: ObservableObject {
//Handles the in-out with the CoreData persistence store
@Environment(\.managedObjectContext) var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \AccountBackEnd.accountID, ascending: true)],
animation: .default)
var accounts: FetchedResults<AccountBackEnd>
//Access Published Objects
@EnvironmentObject var publishedClassAccount: PublishedClassAccount
//Used for button/nav call out
@Environment(\.presentationMode) var presentationMode
func addAccount() {
withAnimation {
//Adds to persistence store
let newAccount = AccountBackEnd(context: viewContext)
newAccount.accountCompanyName = publishedClassAccount.accountCompanyNamePublished
newAccount.accountAddress = publishedClassAccount.accountAddressPublished
PersistenceController.shared.save
{
error in
if let error = error {
print(error.localizedDescription)
return
}
print("Successfully saved account.")
}
//Exits view
self.presentationMode.wrappedValue.dismiss()
publishedClassAccount.accountCompanyNamePublished = ""
}
}
}
This is the view that first allows the user to add an account:
import SwiftUI
import CoreData
//View for user to add a new account with
struct AddAccountView: View {
//Handles the in-out with the CoreData persistence store
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \AccountBackEnd.accountID, ascending: true)],
animation: .default)
private var accounts: FetchedResults<AccountBackEnd>
//Access Published Objects
@EnvironmentObject var publishedClasses: PublishedClassAccount
//Used for button/nav call out
@Environment(\.presentationMode) var presentationMode
//Calls func for refactoring
@StateObject var vm = funcTest()
var body: some View {
ScrollView {
VStack {
Group {
MainAddHeaderView(mainTextField: "Account", iconField: "building")
}
Group{
AddAccountCompanyName()
ViewSpacer()
AddAccountAddress()
ViewSpacer()
AddAccountDetails()
ViewSpacer()
Button(action: vm.addAccount) {
LargeSaveButtonBlue(saveButtonLabel: "Save Changes")
}
.environmentObject(publishedClasses)
}
ViewSpacer()
LargeDeleteButton(deleteButtonLabel: "Cancel Changes")
ViewSpacer()
}
}
.navigationBarHidden(true)
}
}
And this is the view that is meant to display the Account after it's been entered:
import SwiftUI
import CoreData
struct AccountDetailMain: View {
//Takes object from @StateObject, presents as var
@ObservedObject var accountBackEnd: AccountBackEnd
var body: some View {
ScrollView {
VStack {
MainHeaderViewTop(mainTextField: accountBackEnd.accountCompanyName ?? "", iconField: "building")
}
Spacer()
.frame(height: 5)
HStack {
NavigationLink {
EditAccountView()
} label: {
MainHeaderViewBottomLeft()
}
Spacer()
NavigationLink {
AddAccountView()
} label: {
SubHeaderViewIcon(subheaderIcon: "plus.square", subheaderIconColor: Color("EditButtonBlue"))
}
}
ViewSpacer()
Group {
SalesRecords()
ViewSpacer()
LatestThreeQuotes()
ViewSpacer()
LatestNote()
ViewSpacer()
}
Group {
AccountsContactsView()
ViewSpacer()
BranchContactInfoView()
ViewSpacer()
AccountAddressView()
ViewSpacer()
RepDetailsView()
ViewSpacer()
}
Group {
NavigationLink {
EditAccountView()
} label: {
LargeEditButtonGreen(editButtonLabel: "Edit Account")
}
ViewSpacer()
}
}
.navigationBarHidden(true)
//.environmentObject(publishedClasses)
}
}