我正在为我的学校项目开发一个应用程序,但遇到了一个问题,我无法处理它。我正在尝试从我的 Firebase Cloud Firestore 获取
midTerm
、finalTerm
和 lectureGradeId
值。除了这些值之外,我可以从 Firestore 获取所有值。
为了清楚起见,我将代码和 Firestore 结构放在下面:
学生.swift
import Foundation
import FirebaseFirestore
struct Grades: Codable, Hashable {
var lectureGradeId: String
var midTerm: String
var endTerm: String
}
struct Students: Identifiable, Codable {
var id: String
var email: String
var studentName: String
var studentSurname: String
var studentTerm: String
var studentBirthday: String
var studentClass: Int
var studentDept: String
var studentFaculty: String
var studentIsActive: Bool
var studentIsGraduated: Bool
var studentLectures: [String]?
var studentGrades: [Grades]?
}
StudentsViewModel.swift
import Foundation
import Firebase
class StudentsViewModel: ObservableObject {
@Published var students = [Students]()
private var db = Firestore.firestore()
func fetchData() {
db.collection("Students").whereField("id", isEqualTo: "20704029").addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("No documents")
return
}
self.students = documents.map { (queryDocumentSnapshot) -> Students in
let data = queryDocumentSnapshot.data()
let id = data["id"] as? String ?? ""
let email = data["email"] as? String ?? ""
let studentName = data["studentName"] as? String ?? ""
let studentSurname = data["studentSurname"] as? String ?? ""
let studentTerm = data["studentTerm"] as? String ?? ""
let studentBirthday = data["studentBirthday"] as? String ?? ""
let studentClass = data["studentClass"] as? Int ?? 0
let studentDept = data["studentDept"] as? String ?? ""
let studentFaculty = data["studentFaculty"] as? String ?? ""
let studentIsActive = data["studentIsActive"] as? Bool ?? true
let studentIsGraduated = data["studentIsGraduated"] as? Bool ?? false
let studentLectures = data["studentLectures"] as? Array ?? [""]
let student = Students(id: id, email: email, studentName: studentName, studentSurname: studentSurname, studentTerm: studentTerm, studentBirthday: studentBirthday, studentClass: studentClass, studentDept: studentDept, studentFaculty: studentFaculty, studentIsActive: studentIsActive, studentIsGraduated: studentIsGraduated, studentLectures: studentLectures)
//print(student)
return student
}
}
}
}
GradesPage.swift
import SwiftUI
struct GradesPage: View {
@ObservedObject private var viewModel = StudentsViewModel()
var body: some View {
NavigationView {
List(viewModel.students) { student in
VStack(alignment: .leading) {
Text("Student Name: ") + Text(" ") + Text(student.studentName) + Text(" ") + Text(student.studentSurname)
//I want to add the grades to see in here but don't know how to handle it
}
}
}.onAppear {
self.viewModel.fetchData()
}
}
}
我尝试过的解决方案:
提前致谢,欢迎所有帮助!
注意,您应该使用
@StateObject private var viewModel = StudentsViewModel()
。
另请注意,您的代码中没有 finalTerm
并且 NavigationView
已弃用,请使用 NavigationStack
要在
studentGrades
视图中显示 GradesPage
,
只需使用 ForEach
,例如:
struct GradesPage: View {
@StateObject private var viewModel = StudentsViewModel()
var body: some View {
NavigationStack { // <--- here
List(viewModel.students) { student in
VStack(alignment: .leading) {
Text("Student Name: ") + Text(" ") + Text(student.studentName) + Text(" ") + Text(student.studentSurname)
ForEach(student.studentGrades ?? []) { grade in // <--- here
Text(grade.lectureGradeId)
Text(grade.midTerm)
Text(grade.endTerm)
}
}
}
}
.onAppear {
self.viewModel.fetchData()
}
}
}
struct Grades: Identifiable, Codable, Hashable { //<--- here
let id = UUID()
var lectureGradeId: String
var midTerm: String
var endTerm: String
enum CodingKeys: String, CodingKey {
case lectureGradeId, midTerm, endTerm
}
}
struct Students: Identifiable, Codable {
var id: String
var email: String
var studentName: String
var studentSurname: String
var studentTerm: String
var studentBirthday: String
var studentClass: Int
var studentDept: String
var studentFaculty: String
var studentIsActive: Bool
var studentIsGraduated: Bool
var studentLectures: [String]?
var studentGrades: [Grades]?
}