Search code examples
iosswiftrealm

realm data structure for workout tracking app


First time asking a question on StackOverflow, so forgive me if it isn't worded perfectly. I'm in the process of trying to build a fitness tracking iOS app. I'm attempting to use realm to handle the database side of things as I like how easy it is to use/update/etc. That being said, I'm having a hard time figuring HOW to structure my data. Ideally, there's a list of exercises and workouts. My issue is with the workout sets and workouts. I know the workouts should hold a list of exercises like this:

EDIT: Added in the other data structures I currently have that I'm playing around with as well to help better illustrate my issue

class Workout: Object {
    
    @Persisted(primaryKey: true) var _id: ObjectId
    
    //A workout will have many exercises
    @Persisted var exercises: List<Exercise>
}

class Exercise: Object {
    
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var name: String = ""
    @Persisted var equipment: String = ""
    @Persisted var bodyPart: String = ""
    
    @Persisted var workoutSets: List<WorkoutSet>
    
}

class WorkoutSet: Object {

    @Persisted var reps: Int? // Number of reps for the each set
    @Persisted var lbs: Double // Amount of weight/kg for each set
    @Persisted var notes: String? // Notes for each set
    
}

but I'm unsure of how to add the workout sets because I want each workout to unique, while reusing the same exercises. So my question is really, where and how do I track the workout sets?

As pointed out to me, my question was a bit vague. So, for example let's say I have a workout on Monday that has 1 exercise in it called bench press and I do 3 sets of 10 with 135lbs. Then on Wednesday I do a new workout that has bench press in it again and this time I do 4 sets of 8 with 225lbs. I'm getting stuck as to how how/where the workout sets should be in the data scheme because they're tied to an exercise AND a workout. Maybe I'm overthinking the problem too much but I seem to be just going in circles


Solution

  • I think your well on your way an on the right track. Based on the info in your question, you're got some static data the app will provide and then some data the user will enter.

    The static data is the Workouts and Exercises

    class Workout: Object {
        @Persisted(primaryKey: true) var _id: ObjectId
        @Persisted var exercises: List<Exercise>
    }
    
    class Exercise: Object {
        @Persisted(primaryKey: true) var _id: ObjectId
        @Persisted var name: String = ""
        @Persisted var equipment: String = ""
        @Persisted var bodyPart: String = ""
        //@Persisted var workoutSets: List<WorkoutSet> remove!
    }
    

    The dynamic data is when the user selects a Workout (there could be more than 1), they will then select multiple exercises (added to the workout) and then for each one, what they did. For that, you'll need objects that encapsulate all of that data (including the user for future scaleability)

    //this class stores the user and the workouts they selected
    class UserWorkoutDataClass: Object {
       @Persisted user_uid = "" //the users uid
       @Persisted user_workouts = List<UserWorkoutClass> //user can have multiple workouts
    }
    
    //this class are the workouts the user selected and then the exercises they
    //  have done so far within this workout
    class UserWorkoutClass: EmbeddedObject {
       @Persisted which_workout: WorkoutClass! //which workout is this
       @Persisted exercises: List<UserExerciseClass> //what exercises the user has done
    }
    
    //this is the data specific to each exercise within each workout
    class UserExerciseClass: EmbeddedObject {
        @Persisted var which_exercise: ExerciseClass
        @Persisted var reps: Int? 
        @Persisted var lbs: Double
        @Persisted var notes: String?
    }
    

    You'll notice that I made the UserWorkoutClass and the UserExercise class Embedded. The thought there is that both of those objects are very specific to this user so they don't need to be managed separately as they won't be accessed by any other user or objects.

    The above objects will allow for multiple users; each user can add multiple workouts and "track" which exercises they perform for each workout.