I am trying to conform exercise data into the following struct from Firebase:
struct StrengthModel: Decodable {
var day: WorkoutDays
var strengthModel: [ExerciseModel]
}
where WorkoutDays:
struct WorkoutDays: Encodable, Decodable, Identifiable {
var id: String
var name: String
var date: Date
var description: String
}
and ExerciseModel:
struct ExerciseModel: Encodable, Decodable, Hashable, Identifiable {
var workoutDayID: String
var id: String
var name: String
var reps: [Int]
var percent: [Double]
var linkToVideo: String
var isCompleted: Bool
var description: String
var timeToComplete: Double
}
I've used the following call to get data from my Firestore:
func getAllWorkoutData() {
workoutDayData.removeAll()
let db = Firestore.firestore()
let user = self.user?.uid
var tempWorkoutList: [WorkoutDays] = []
var tempExercisesList: [ExerciseModel] = []
db.collection("Users").document(user!).collection("Workout Programs").document(workoutProgramSelected).collection("Days").addSnapshotListener {(querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
tempExercisesList.removeAll()
let data = document.data()
let dayID = data["id"] as? String ?? ""
let dayName = data ["name"] as? String ?? ""
let notes = data ["notes"] as? String ?? ""
let date = (data["date"] as? Timestamp)?.dateValue() ?? Date()
let description = data ["description"] as? String ?? ""
let workoutDays = WorkoutDays(id: dayID, name: dayName, date: date, description: description)
tempWorkoutList.append(workoutDays)
self.notes = notes
self.workoutDayData = tempWorkoutList
db.collection("Users").document(user!).collection("Workout Programs").document(self.workoutProgramSelected).collection("Days").document(dayName).collection("Exercises").addSnapshotListener {(querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let data = document.data()
let workoutDayID = data["workoutDayID"] as? String ?? ""
let id = data["id"] as? String ?? ""
let name = data ["name"] as? String ?? ""
let isCompleted = data["isCompleted"] as? Bool ?? false
let link = data["link"] as? String ?? ""
let pct = data["programmedPCT"] as? [Double] ?? []
let reps = data["programmedReps"] as? [Int] ?? []
let description = data["Description"] as? String ?? ""
let timeToComplete = data["timeToComplete"] as? Double ?? 0.0
let exercises = ExerciseModel(workoutDayID: workoutDayID, id: id, name: name, reps: reps, percent: pct, linkToVideo: link, isCompleted: isCompleted, description: description, timeToComplete: timeToComplete)
self.exerciseData.append(exercises)
tempExercisesList.append(exercises)
self.exerciseData = tempExercisesList
} }
}
} }
}
doing this, I can get a list of WorkoutDays data and a list of Exercise data, but I'm having trouble combining the workoutDay data with the Exercise data to conform to a single struct so that I can effectively show the user a full day of exercises.
Any help would be much appreciated. Thanks in advance!!!
I've tried many ways around this problem, including a completion block that loops through workoutDayData and ExerciseData:
func organizeExerciseDataRun() -> [newStrengthModel]{
var model: [newStrengthModel] = []
var secondTempExerciseList: [ExerciseModel] = []
getAllWorkoutData { (data) in
for day in data.day{
secondTempExerciseList.removeAll()
for exercise in data.strengthModel {
if day.id == exercise.workoutDayID {
secondTempExerciseList.append(exercise)
}
model.append(newStrengthModel(day: day, strengthModel: secondTempExerciseList))
}
}
}
return model
}
which didn't work at all.
I also tried a for loop in my getAllWorkoutData() function, but that gives me an empty array for dayAndExerciseList as well :
for day in self.workoutDayData {
var secondTempExerciseList: [ExerciseModel] = []
secondTempExerciseList.removeAll()
for exercise in exerciseData {
if day.id == exercise.workoutDayID {
secondTempExerciseList.append(exercise)
}
self.dayAndExerciseList.append(newStrengthModel(day: day, strengthModel: secondTempExerciseList))
}
}
I've also tried putting all of my data as a map so that I don't need to access the sub-collection view, but that doesnt seem to work either as I don't know how to loop through the map in the firebase call:
I'm not particularly tied to any solution, so any help would make my day!