I have two models, ExerciseModel and RoutineModel, in which a single routine is comprised of one or more exercises. I am trying to use the contents of the data array from the ExerciseArrayObject class as part of my RoutineArrayObject's data array.
I am receiving the following error:
'self' used in property access 'exercises' before all stored properties are initialized
Here is ExerciseArrayObject:
import Foundation
import SwiftUI
class ExerciseArrayObject: ObservableObject {
@Published var dataArray = [ExerciseModel]()
init() {
//print("FETCH FROM DATABASE HERE")
let exercise1 = ExerciseModel(exerciseID: "", userID: "", username: "userA", exerciseTitle: "Exercise 1", dateCreate: Date(), exerciseImage: "logo", repsInfo: "12 reps", setsInfo: "3 sets")
let exercise2 = ExerciseModel(exerciseID: "", userID: "", username: "userB", exerciseTitle: "Exercise 2", dateCreate: Date(), exerciseImage: "logo", repsInfo: "8 reps", setsInfo: "4 sets")
let exercise3 = ExerciseModel(exerciseID: "", userID: "", username: "userC", exerciseTitle: "Exercise 3", dateCreate: Date(), exerciseImage: "logo", repsInfo: "5 reps", setsInfo: "5 sets")
let exercise4 = ExerciseModel(exerciseID: "", userID: "", username: "userD", exerciseTitle: "Exercise 4", dateCreate: Date(), exerciseImage: "logo", repsInfo: "20 reps", setsInfo: "10 sets")
let exercise5 = ExerciseModel(exerciseID: "", userID: "", username: "userE", exerciseTitle: "Exercise 5", dateCreate: Date(), exerciseImage: "logo", repsInfo: "10 reps", setsInfo: "3 sets", sharedUserUsername: "Shared User")
self.dataArray.append(exercise1)
self.dataArray.append(exercise2)
self.dataArray.append(exercise3)
self.dataArray.append(exercise4)
self.dataArray.append(exercise5)
}
}
And here is RoutineArrayObject:
class RoutineArrayObject: ObservableObject {
@ObservedObject var exercises: ExerciseArrayObject
@Published var dataArray = [RoutineModel]()
init() {
//print("FETCH FROM DATABASE HERE")
let routine1 = RoutineModel(routineID: "", userID: "", username: "user1", routineTitle: "Yoga Routine", exercises: exercises.dataArray, dateCreate: Date(), routineImage: "demoexercise", noOfExercises: "\(exercises.dataArray.count)")
let routine2 = RoutineModel(routineID: "", userID: "", username: "user2", routineTitle: "Core Routine", exercises: exercises.dataArray, dateCreate: Date(), routineImage: "logo", noOfExercises: "\(exercises.dataArray.count)", sharedUserID: "", sharedUserUsername: "Shared User")
self.dataArray.append(routine1)
self.dataArray.append(routine2)
}
}
CodePudding user response:
Assuming ExerciseModel
and RoutineModel
are structs,
you could try this approach using completion closures. This
keeps your two models and use the contents of the data array from
the ExerciseArrayObject
class as part of your RoutineArrayObject
's data array.
class ExerciseArrayObject: ObservableObject {
@Published var dataArray = [ExerciseModel]()
init() {
ExerciseArrayObject.fetchExcersices() { arr in
self.dataArray = arr
}
}
static func fetchExcersices(completion: @escaping([ExerciseModel]) -> ()) {
//print("FETCH FROM DATABASE HERE")
var excersices = [ExerciseModel]()
let exercise1 = ExerciseModel(exerciseID: "", userID: "", username: "userA", exerciseTitle: "Exercise 1", dateCreate: Date(), exerciseImage: "logo", repsInfo: "12 reps", setsInfo: "3 sets")
let exercise2 = ExerciseModel(exerciseID: "", userID: "", username: "userB", exerciseTitle: "Exercise 2", dateCreate: Date(), exerciseImage: "logo", repsInfo: "8 reps", setsInfo: "4 sets")
let exercise3 = ExerciseModel(exerciseID: "", userID: "", username: "userC", exerciseTitle: "Exercise 3", dateCreate: Date(), exerciseImage: "logo", repsInfo: "5 reps", setsInfo: "5 sets")
let exercise4 = ExerciseModel(exerciseID: "", userID: "", username: "userD", exerciseTitle: "Exercise 4", dateCreate: Date(), exerciseImage: "logo", repsInfo: "20 reps", setsInfo: "10 sets")
let exercise5 = ExerciseModel(exerciseID: "", userID: "", username: "userE", exerciseTitle: "Exercise 5", dateCreate: Date(), exerciseImage: "logo", repsInfo: "10 reps", setsInfo: "3 sets", sharedUserUsername: "Shared User")
excersices.append(exercise1)
excersices.append(exercise2)
excersices.append(exercise3)
excersices.append(exercise4)
excersices.append(exercise5)
completion(excersices) // <-- todo deal with errors etc...
}
}
class RoutineArrayObject: ObservableObject {
@Published var dataArray = [RoutineModel]()
init() {
ExerciseArrayObject.fetchExcersices() { exercises in
print("--> exerciseArray: \(exercises)")
self.fetchRoutines(exercises: exercises) { _ in
print("--> routineArray: \(self.dataArray)")
}
}
}
func fetchRoutines(exercises: [ExerciseModel], completion: @escaping(Bool) -> ()) {
//print("FETCH FROM DATABASE HERE")
let routine1 = RoutineModel(routineID: "", userID: "", username: "user1", routineTitle: "Yoga Routine", exercises: exercises, dateCreate: Date(), routineImage: "demoexercise", noOfExercises: exercises.count)
let routine2 = RoutineModel(routineID: "", userID: "", username: "user2", routineTitle: "Core Routine", exercises: exercises, dateCreate: Date(), routineImage: "logo", noOfExercises: exercises.count, sharedUserID: "", sharedUserUsername: "Shared User")
self.dataArray.append(routine1)
self.dataArray.append(routine2)
completion(true) // <-- todo deal with errors etc...
}
}
You can also use other techniques instead of basic completion closures, such as async/await concurrency with tasks.