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:
privatevarquickPose=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:
classMyCustomExercise{staticfunc createExercise(hideFeedback:Bool=true)->CustomExercise{letstages=[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...
]letrequiredFeatures:[QuickPose.Feature]=[.rangeOfMotion(.elbow(side:.right, clockwiseDirection:true), style: lightOverlayStyle),
// Add required features...
]returnCustomExercise(
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.