kinestex-sdk-react-native
v1.4.0
Published
A React Native SDK for integrating KinesteX AI Fitness & Physio in your project.
Maintainers
Readme
Precise Motion Tracking and Analysis SDK
Stay Ahead with KinesteX AI Motion Tracking.
Available Integration Options
Integration Options
| Integration Option | Description | Features | Details | |--------------------------------|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| | Complete User Experience | Leave it to us to recommend the best workout routines for your customers, handle motion tracking, and overall user interface. High level of customization based on your brand book for a seamless experience. | - Long-term lifestyle workout plans - Specific body parts and full-body workouts - Individual exercise challenges (e.g., 20 squat challenge) | View Integration Options | | Custom User Experience | Integrate the camera component with motion tracking. Real-time feedback on all customer movements. Control the position, size, and placement of the camera component. | - Real-time feedback on customer movements - Communication of every repeat and mistake - Customizable camera component position, size, and placement | View Details |
Configuration
Permissions
AndroidManifest.xml
Add the following permissions for camera and microphone usage:
<!-- Add this line inside the <manifest> tag -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>Info.plist
Add the following keys for camera and microphone usage:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for video streaming.</string>Install libraries
Install kinestex-sdk & webview:
npm install kinestex-sdk-react-native react-native-webviewIf you are using expo to build your app, you need to install kinestex-sdk-react-native with the following command:
npx expo install react-native-webviewUsage
Initial Setup
Prerequisites: Ensure you’ve added the necessary permissions in
AndroidManifest.xmlandInfo.plist.Launching the View: To display the AI training, KinesteX SDK uses an internal webview library. We have multiple launch options in KinesteXSDK, and based on the option you select, you need to adjust the parameters you are sending to us.
Integration Options
| enum IntegrationOption | Description | |----------------------------|-----------------------------------------------------------------| | MAIN | Integration of our Complete UX | | PLAN | Integration of Individual Plan Component | | WORKOUT | Integration of Individual Workout Component | | CHALLENGE | Integration of Individual Exercise in a challenge form | | EXPERIENCE | Integration of our Experience component. Contact support for more details | | CAMERA | Integration of our camera component with pose-analysis and feedback |
MAIN Integration Option
Available Categories to Sort Plans
| Plan Category (key: planCategory) | |---------------------------------------| | Strength | | Cardio | | Weight Management | | Rehabilitation |
Example Integration
- Create a reference to KinesteXSDK component:
const kinestexSDKRef = useRef<KinesteXSDKCamera>(null);- Create a
postDataobject:
const postData: IPostData = {
key: apiKey, // your API key
userId: 'YOUR USER ID', // your unique user identifier
company: 'YOUR COMPANY', // your company name
planCategory: PlanCategory.Cardio, // plan category you'd like to present to your user
age: 50, // Use null if you do not want to specify
height: 150, // In cm. Use null if you do not want to specify
weight: 200, // In kg. Use null if you do not want to specify
gender: 'Male', // Use null if you do not want to specify
lifestyle: Lifestyle.Sedentary, // Use null if you do not want to specify
};- Handle messages we send back to you according to what your users do in real-time:
const handleMessage = (type: string, data: { [key: string]: any }) => {
switch (type) {
case 'exit_kinestex':
console.log("User wishes to exit the app");
if (data.message) {
console.log('Date:', data.message);
}
dismissKinesteX(); // hide KinesteX WebView
break;
case "plan_unlocked":
console.log('Workout plan unlocked:', data);
break;
// All other message types (see below in Data Points section)
default:
console.log('Other message type:', type, data);
break;
}
};- Display KinesteXSDK with Main Integration Option:
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.MAIN}
handleMessage={handleMessage}
/>PLAN Integration Option
You do not have to specify planCategory in this integration option as you would specify the plan directly.
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.PLAN} // PLAN integration option
plan={"Circuit Training"} // exact name of the workout plan you want to display
handleMessage={handleMessage}
/>WORKOUT Integration Option
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.WORKOUT} // WORKOUT integration option
workout={"Circuit Training"} // exact name of the workout you want to display
handleMessage={handleMessage}
/>CHALLENGE Integration Option
- Modify
postDatato include the exercise and duration of the challenge:
const postData: IPostData = {
key: apiKey,
userId: 'YOUR USER ID',
company: "YOUR COMPANY NAME",
exercise: 'Squats', // name of the exercise
countdown: 100, // duration of challenge in seconds
};- Select integration option in KinesteXSDK:
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.CHALLENGE}
handleMessage={handleMessage}
/>EXPERIENCE Integration Option
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.EXPERIENCE} // EXPERIENCE integration option
experience={"box"} // exact name of the experience you want to display
handleMessage={handleMessage}
/>CAMERA Integration Option
- Modify
postDatato include the current exercise and all expected exercises a person should do:
const postData: IPostData = {
key: apiKey,
userId: 'YOUR USER ID',
company: 'YOUR COMPANY NAME',
currentExercise: 'Squats', // current exercise
exercises: ['Squats', 'Jumping Jack'], // all exercises a person should do. We will preload them for future usage
};- Changing current exercise:
const changeExercise = () => {
kinestexSDKRef.current?.changeExercise("Jumping Jack"); // the exercise has to be from the list of exercises otherwise it wouldn't load
};- Displaying KinesteXSDK:
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.CAMERA}
handleMessage={handleMessage}
/>- Handle message for reps and mistakes a person has done:
const handleMessage = (type: string, data: { [key: string]: any }) => {
switch (type) {
case "successful_repeat":
console.log('Current rep:', data.value);
break;
case "mistake":
console.log('Mistake:', data.value);
break;
default:
console.log('Unknown message type:', type, data);
break;
}
};Warmup (optional)
Load KinesteX before the user opens it, so it appears instantly. Both options are opt-in. Without the new props the SDK behaves exactly as before.
When you know what you will open
Render the same component you would normally render, with visible={false}. It loads off screen with zero size and takes no space in your layout. Set visible to true to show it.
const [isOpen, setIsOpen] = useState(false);
<KinestexSDK
ref={kinestexSDKRef}
data={postData}
integrationOption={IntegrationOption.WORKOUT}
workout={"Fitness Lite"}
visible={isOpen} // false = warm up hidden, true = show
onWarmupStateChange={(state) => {}} // optional: "loading" | "ready" | "failed"
handleMessage={handleMessage}
/>Rules that matter:
visiblemust only say whether the user has KinesteX open. Never derive it fromonWarmupStateChange, for examplevisible={isOpen && state === "ready"}. A view that loads fresh when shown reportsloadingagain, which would hide it and loop. Use the state only for your own UI, such as enabling a button.- While hidden,
handleMessagereceives nothing. Messages such askinestex_launchedare delivered in order the moment you show the view. - The component must stay mounted in the same place between warming and showing. With React Navigation, mount it once above your navigator and let it fill the screen only while open, so it never blocks touches while hidden:
<View style={isOpen ? StyleSheet.absoluteFill : undefined} pointerEvents="box-none">
<KinestexSDK visible={isOpen} {...rest} />
</View>- The page reads
dataonce, when it loads. When shown, the SDK loads fresh ifdataor the target changed while hidden, if the hidden load failed, or if the warm page is older than 15 minutes. The worst case is a normal cold start. Keepdatastable, for example withuseMemo, to keep the warmup. CAMERA,EXPERIENCEand any launch usinginstantRedirectcould open the camera on load, so while hidden they only load the warmup page below.readythen means the caches are warm, and the real page loads when shown.- Setting
visibleback tofalsereplaces the used page with the warmup page. The next open is a normal load from warm caches, not an instant one. Unmount the component when you no longer need it. - A hidden load of a real page is a real page load for KinesteX: it authenticates and is recorded in analytics as an open, even if the user never sees it. Warm up when the user is likely to open KinesteX, not on every app start.
- Messages delivered when shown were produced at load time, so dates inside
kinestex_launchedare load times, andtime_spentinexit_kinestexincludes the time spent hidden. - Keep a single hidden instance, and unmount it when the user is unlikely to open KinesteX soon. A warmed instance holds the full web app and its pose model in the WebView process, a few hundred MB, the same as a visible one. Unmounting frees all of it.
When you do not know yet
Render KinestexWarmup anywhere, for example after login. It authenticates and caches the app, the theme and the pose model, so any KinestexSDK mounted later loads from cache. Unmount it before you show KinesteX, so two copies of the web app are never in memory together.
import KinestexSDK, { KinestexWarmup } from "kinestex-sdk-react-native";
<KinestexWarmup data={postData} />KinestexWarmup accepts an optional handleMessage. It receives data events only, for example a workout that was saved from the offline queue, and never kinestex_loaded, kinestex_launched or error_occurred.
Available Data Points
The KinesteX SDK provides various data points that are returned through the message callback. Here are the available data types:
| Type | Data | Description |
|----------------------------|----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
| kinestex_launched | dd mm yyyy hours:minutes:seconds | When a user has launched KinesteX |
| exit_kinestex | date: dd mm yyyy hours:minutes:seconds, time_spent: number | Logs when a user clicks the exit button and the total time spent |
| plan_unlocked | title: String, date: date and time | Logs when a workout plan is unlocked by a user |
| workout_opened | title: String, date: date and time | Logs when a workout is opened by a user |
| workout_started | title: String, date: date and time | Logs when a workout is started by a user |
| exercise_completed | time_spent: number, repeats: number, calories: number, exercise: string, mistakes: [string: number] | Logs each time a user finishes an exercise |
| total_active_seconds | number | Logs every 5 seconds, counting the active seconds a user has spent working out |
| left_camera_frame | number | Indicates that a user has left the camera frame |
| returned_camera_frame | number | Indicates that a user has returned to the camera frame |
| workout_overview | workout: string, total_time_spent: number, total_repeats: number, total_calories: number, percentage_completed: number, total_mistakes: number | Logs a complete summary of the workout |
| exercise_overview | [exercise_completed] | Returns a log of all exercises and their data |
| workout_completed | workout: string, date: dd mm yyyy hours:minutes:seconds | Logs when a user finishes the workout and exits the workout overview |
| active_days (Coming soon)| number | Represents the number of days a user has been opening KinesteX |
| total_workouts (Coming soon)| number | Represents the number of workouts a user has done since starting to use KinesteX |
| workout_efficiency (Coming soon)| number | Represents the level of intensity with which a person has completed the workout |
Contact
If you have any questions, contact: [email protected]
