3

I'm doing a project with Swift using SwiftUI(which I'm kind of new) and Firebase.

I want to display information on a List View from the data I retrieved from Firebase and stored in an array of dictionaries and that works fine because I can display the information I want to see in the List cells in the console but Swift is not accessing the ForEach loop where I am reading the data of the array.

What I have tried:

  1. Add id: \.self to the ForEach loop.
  2. Made the CourseInfo struct to conform to the Hashable protocol.

Then I realized that it is actually not entering the ForEach loop.

I'll leave my code down below.

Thanks.

Course.swift

import Foundation
import FirebaseAuth
import FirebaseFirestore

struct CourseInfo:Identifiable {
    let id = UUID()
    let courseName: String
    let totalStudents: Int
    let courseID: String
}

class Course: ObservableObject {
    let user = Auth.auth().currentUser
    let db = Firestore.firestore()
  
    @Published var courses = [CourseInfo]()
    
    func retreiveData() {
        // Check if the user is signed in.
        if user != nil {
            // if user is signed in --> retreive all of the user's courses and info.
            db.collection("courses").getDocuments() { [self] (querySnapshot, error) in
                // Check for errors.
                if let error = error {
                    print(error.localizedDescription)
                }
                else { // if there are not errors.
                    for course in querySnapshot!.documents {
                        let courseInfo = course.data()
                        manageData(courseInfo)
                    }
                }
            }
        }
    }// end retreiveData()
    
    private func manageData(_ courseInfo: [String : Any]) {
        var courseName: String = ""
        var students: [Any] = []
        var courseID: String = ""
        
        for (key, value) in courseInfo {
            if key == "Teacher" && value as! String == user!.uid {
                for (key, value) in courseInfo {
                    if key == "Course Name" {
                        courseName = value as! String
                    }
                    else if key == "Course ID" {
                        courseID = value as! String
                    }
                    else if key == "Students"{
                        students = value as! Array<Any>
                    }
                }
                self.courses.append(CourseInfo(courseName: courseName, totalStudents: students.count, courseID: courseID))
            }
        }
        
    } // end manageData()
}

CourseListView.swift

import SwiftUI

struct CourseListView: View {
    var thaCourse:[CourseInfo] = Course().courses
    
    var body: some View {
        List {
            ForEach(thaCourse) { course in
                CourseCell(course: course)
            }
        }
    }
}

struct CourseCell: View {
    var course: CourseInfo
    
    var body: some View {
        VStack(alignment:.leading, spacing: 3) {
            
            Text(course.courseName)
                .font(.title2)
                .fontWeight(.semibold)
                .lineLimit(2)
                .minimumScaleFactor(0.5)
            
            Text("Total de alumnos: \(course.totalStudents)")
            
            Text("ID: \(course.courseID)")
        }
    }
}

1 Answer 1

-1

You need to declare your Course class as a @StateObject (or @ObservedObject) property in your view and then access the array via that property. You also need to fetch your data, here I do it when the view appears using onAppear

@StateObject var course: Course = Course()

var body: some View {
    List {
        ForEach(course.courses) { course in
            CourseCell(course: course)
        }
    }
    .onAppear {
        course.retreiveData()
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.