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.