This project provides the end-to-end demo solution for an AR/AI fitness iOS app. FitCount is based on the QuickPose.ai SDK.
For more explanation of the code in this repository please check our FitCount Guide
- Clone the repository.
- Register for a free SDK key at our Development portal.
- Open the project in Xcode.
- Add your SDK key to the
Workout/QuckPoseBasicView.swiftfile to this line:
private var quickPose = QuickPose(sdkKey: "YOUR SDK KEY") // register for your free key at https://dev.quickpose.ai
- Run the project on your physical device. Note that due to the Apple's limitations, the SDK will not work on the simulator.
- Counting fitness exercises (Squats, Bicep Curls) repetitions based on user's movement.
- Custom Exercise Engine - Create your own exercises with custom angle ranges and stages
- Understand if a user is present on the screen with .inside feature
- Audio and text feedback and guidance.
- Instructions before the workout.
- Local workout history.
FitCount includes a powerful custom exercise system that allows you to create exercises beyond the built-in QuickPose exercises. Custom exercises use angle ranges and exercise stages to track complex movements.
The app includes three pre-built custom exercises:
- Side Tilts (
SideTiltsExercise.swift) - Lateral bending exercise with alternating arm movements - Knee Raises (
KneeRaisesExercise.swift) - Alternating knee raises with arm position tracking - Front Push-up (
FrontPushupExercise.swift) - Push-up tracking with top and bottom position detection
Custom exercises are defined using:
- Exercise Stages: Sequential positions that define one complete repetition
- Joint Angles: Specific angle ranges (min/max) for joints like elbows, shoulders, knees, and hips
- Range of Motion Tracking: QuickPose features that track joint movements
- Feedback System: Optional real-time feedback for correct form
Each custom exercise cycles through its stages, and when all stages are completed, a rep is counted.
To create a new custom exercise:
- Create a new Swift file following the naming pattern:
[ExerciseName]Exercise.swift - Define your exercise stages with joint angle requirements:
class MyCustomExercise { static func createExercise(hideFeedback: Bool = true) -> CustomExercise { let stages = [ ExerciseStage( id: "stage_1", name: "Stage 1", requirements: [ .elbow(side: .right): AngleRange(min: 160, max: 210), .knee(side: .right): AngleRange(min: 150, max: 200) ], description: "Description of this stage" ), // Add more stages... ] let requiredFeatures: [QuickPose.Feature] = [ .rangeOfMotion(.elbow(side: .right, clockwiseDirection: true), style: lightOverlayStyle), // Add required features... ] return CustomExercise( id: "my_exercise", name: "My Exercise", description: "Exercise description", stages: stages, requiredFeatures: requiredFeatures, hideFeedback: hideFeedback ) } }
- Register your exercise in
QuickPoseBasicView.swiftin the.introExercisecase:
else if sessionConfig.exercise.name == "My Exercise" { customExerciseEngine = CustomExerciseEngine(exercise: MyCustomExercise.createExercise()) }
- Use 2 stages for simple repetitive exercises (like push-ups: top position → bottom position)
- Use 4+ stages for alternating exercises (like knee raises: start → right knee up → center → left knee up)
- Test angle ranges by checking the overlay feedback during exercise execution
- Set hideFeedback: false during development to see real-time angle feedback
- Make sure angle ranges have enough tolerance (typically 40-60 degrees) to account for natural variation
- Register for a free SDK key at our Development portal.
- Check out our GitHub Repository and Getting Started Guide.