Details about goal: I want to fetch data from firebase, list the data in rows in the format of question and answer. The answer will have a textfield to update it. There is a save button that will save the answers by uploading the question and answers to firebase.
Expectation vs results: Expected a button in my main menu when tapped to navigate to the screen. The result is my app freezes, and in the console I get the following error.
Error
Fatal error: No ObservableObject of type AllQuestionsAndAnswersClass found.
A View.environmentObject(_:) for AllQuestionsAndAnswersClass may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-39.4.4/Core/EnvironmentObject.swift, line 55
2020-01-24 13:21:25.523326-0600 FirebaseStarterApp[5025:894100] Fatal error: No ObservableObject of type AllQuestionsAndAnswersClass found.
A View.environmentObject(_:) for AllQuestionsAndAnswersClass may be missing as an ancestor of this view.: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-39.4.4/Core/EnvironmentObject.swift, line 55
My Thoughts I'm not too sure where to start but I think it has to do with having to add the environment object to the preview and do something in App Delegate. I have seen somethings about Scene Delegate but I only have App Delegate, I'm not sure if there is a difference
What I have tried I have tried to look at the following links but they did not help for my case SwiftUI @EnvironmentObject error: may be missing as an ancestor of this view
No ObservableObject of type found
Here is my code for the SwiftUI Screen
@available(iOS 13.0, *)
final class AllJobDataClass: ObservableObject {
@Published var allJobDataArray = [JobInfo]()
}
@available(iOS 13.0, *)
final class AllQuestionsAndAnswersClass: ObservableObject {
@Published var questionsAndAnswersInfoArray = [QuestionAndAnswer]()
}
@available(iOS 13.0.0, *)
struct SingleQuestionAndAnswerRow: View {
@State var singleQuestionAndAnswerVar: QuestionAndAnswer
var body: some View {
return HStack{
Text("\(singleQuestionAndAnswerVar.question)")
TextField("Enter some text", text: $singleQuestionAndAnswerVar.answer)
.border(Color.black)
}
}
}
@available(iOS 13.0.0, *)
struct NewQuestionsScreenSwiftUIView: View {
@EnvironmentObject var allJobDataVar: AllJobDataClass
@EnvironmentObject var allQuestionsAndAnswerVar: AllQuestionsAndAnswersClass
init()
{
fetchDataFromFirebase()
}
var body: some View {
ScreenBackground
{
List(self.allQuestionsAndAnswerVar.questionsAndAnswersInfoArray) { questionAndAnswer in
//here is where questionAnswerRow is presented
SingleQuestionAndAnswerRow(singleQuestionAndAnswerVar: questionAndAnswer)
}
}
.onTapGesture {
self.endEditingFunction()
}
}
}
@available(iOS 13.0.0, *)
struct NewQuestionsScreenSwiftUIView_Previews: PreviewProvider {
static var previews: some View {
NewQuestionsScreenSwiftUIView()
}
}
My code for App Delegate
import UIKit
import Firebase
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Window setup
FirebaseApp.configure()
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = UINavigationController(rootViewController: ATCClassicLandingScreenViewController(nibName: "ATCClassicLandingScreenViewController", bundle: nil))
window?.makeKeyAndVisible()
return true
}
}
You have declarations for environment objects as
struct NewQuestionsScreenSwiftUIView: View {
@EnvironmentObject var allJobDataVar: AllJobDataClass
@EnvironmentObject var allQuestionsAndAnswerVar: AllQuestionsAndAnswersClass
but you must inject them somewhere before NewQuestionsScreenSwiftUIView usage, say on creation (or implicitly via parent view). In provided code it is not visible where you create NewQuestionsScreenSwiftUIView(), but in that place it should be something like
NewQuestionsScreenSwiftUIView()
.environmentObject(AllJobDataClass()) // < or instance if created before
.environmentObject(AllQuestionsAndAnswersClass()) // < or instance if created before
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With