#ios #swift #swiftui
Вопрос:
В настоящее время я пытаюсь создать приложение, которое извлекает данные из Firebase, и у меня возникли некоторые проблемы. Я пытаюсь создать карточку профиля, в которой будут отображаться некоторые данные, прикрепленные к user.uid, но как только я выхожу из системы и снова вхожу, я получаю сообщение об ошибке:
Fatal error: No ObservableObject of type UserDataManager found. A View.environmentObject(_:) for UserDataManager may be missing as an ancestor of this view.
Файл Приложения:
import SwiftUI
import Firebase
@main
struct Darbo_ManijaApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
let viewModel = AppViewModel()
let userdataManager = UserDataManager()
ContentView()
.environmentObject(viewModel)
.environmentObject(userdataManager)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}
Файл UserDataManager:
import Foundation
import Firebase
class UserDataManager: ObservableObject {
@Published var userFirstName: String = ""
init() {
fetchUser()
}
func fetchUser() {
let db = Firestore.firestore()
let userID = Auth.auth().currentUser?.uid ?? "Not Found"
db.collection("users").document(userID)
.addSnapshotListener { documentSnapshot, error in
guard let document = documentSnapshot else {
print("Error fetching document: (error!)")
return
}
guard let data = document.data() else {
print("Document data was empty.")
return
}
print("Fetched Data")
self.userFirstName = data["firstname"] as? String ?? ""
}
}
}
ContentView File:
struct ContentView: View {
@EnvironmentObject var userdataManager: UserDataManager
@EnvironmentObject var viewModel : AppViewModel
var body: some View {
if viewModel.isSignedIn {
UIKitTabView {
JobListView().environmentObject(userdataManager).environmentObject(viewModel).tab(title: "Pradžia", image: "network")
JobListView().tab(title: "Žinutės", image: "message")
LoginView().tab(title: "Paskyra", image: "person")
}
} else {
LoginView()
}
}
}
And the JobsList view:
struct JobListView: View {
@EnvironmentObject var viewModel : AppViewModel
@EnvironmentObject var userdataManager: UserDataManager
let firebaseUserID = Auth.auth().currentUser?.uid ?? "Not Found"
var body: some View {
NavigationView{
ScrollView{
VStack(alignment: .leading, spacing: 0) {
Text("Test")
Text("User ID is: (firebaseUserID)")
Text("My Name is: (userdataManager.userFirstName)")
ForEach(jobData, id: .id) { job in
JobCardView(job: job)
}
}
.frame(minWidth: 0,
maxWidth: .infinity,
minHeight: 0,
maxHeight: .infinity)
.padding()
}
.navigationBarItems(leading:
HStack{
Image("TextDM")
.resizable()
.scaledToFit()
.frame(height: 15)
})
.navigationBarItems(trailing:
HStack{
Button(action: {
viewModel.signOut()
}) {
Image(systemName: "person.crop.circle")
.accentColor(Color.primary)
}
})
.navigationBarTitle("")
.navigationBarTitleDisplayMode(.inline)
.onAppear(){
userdataManager.fetchUser()
}
}
.environmentObject(userdataManager)
.environmentObject(viewModel)
}
}
Сначала я подумал, что это может быть проблемой, потому что в представлении содержимого при вызове элемента tabbaritem объект не задан, но, несмотря на то, что я это сделал, проблема остается. Как я уже упоминал, я получаю сообщение об ошибке на JobListView файл, где я использую текст(«мое имя: (userdataManager.userFirstName)») в первый раз приложение запускается, и если я вошел в систему, нет и ошибки .onAppear с объектами работы, а также выхода из системы, но когда я выйти из системы и снова войти в систему, я получаю выше сообщение об ошибке. Есть какие-либо предложения или советы о том, как это исправить?
Заранее спасибо!
ПРАВКА: Проблема решена. Проблема заключалась в том, что я использовал другое представление вкладок, которое должно было включать объекты ObservableObjects в каждую ссылку на вкладку. Спасибо за помощь!
Ответ №1:
Я не могу воспроизвести проблему с помощью моей текущей установки, но есть несколько вещей, которые я сделал бы по-другому в вашем коде.
в «Darbo_ManijaApp» поместите их за пределы «тела»
let viewModel = AppViewModel()
let userdataManager = UserDataManager()
Убедитесь, что в «Представлении содержимого» последовательность @EnvironmentObject сначала «AppViewModel», а затем «UserDataManager».
что важно, также проходите
.environmentObject(userdataManager).environmentObject(viewModel)
к другому «Просмотр вакансий ()».
И еще раз убедитесь, что последовательность @EnvironmentObject верна.
Комментарии:
1. Спасибо за ответ! Я попробовал то, что вы предложили, но теперь я получаю следующую ошибку: ** «Экземпляр FirebaseApp по умолчанию должен быть настроен, прежде чем можно будет инициализировать аутентификацию по умолчанию. Один из способов убедиться в этом-вызвать
FirebaseApp.configure()
делегата приложенияapplication(_:didFinishLaunchingWithOptions:)
(или инициализатор@main
структуры в SwiftUI)».**