@sency/react-native-smkit-ui
v2.2.2
Published
React Native library for SMKit UI - Advanced fitness assessments and workout programs with AI-powered motion detection and real-time performance tracking
Downloads
723
Readme
React Native SMKit UI Library
AI-powered fitness assessments, custom workouts, and workout programs with real-time motion detection for React Native apps.
Table of Contents
- Features
- Requirements
- Installation
- Platform Setup
- Getting Started
- Core Features
- API Reference
- Examples
- Troubleshooting
- Support
Features
- Fitness Assessments - AI-driven fitness evaluations tailored to user fitness levels
- Workout Programs - Multi-week customizable workout plans with progression tracking
- Motion Detection - Real-time motion capture and analysis with pose detection
- Multiple Assessment Types - Fitness, Body360, Strength, Cardio, and custom assessments
- Cross-Platform - Native support for iOS and Android
- Configurable Workouts - Customize by body zone, difficulty, and duration
- Intelligent Model Selection (Android) - Automatically selects the best pose estimation model based on device capabilities for optimal performance
Requirements
General
- Node.js 18+
- npm or yarn
iOS
- iOS 13+
- Xcode 14+
- CocoaPods
Android
- Android API 26+
- Android Studio with SDK tools
- JDK 11+
Installation
Install the package via npm:
npm install @sency/react-native-smkit-uiOr with yarn:
yarn add @sency/react-native-smkit-uiThen install native dependencies:
cd ios && pod install && cd ..Platform Setup
iOS Setup
- Add the required CocoaPods sources to your
ios/Podfile:
source 'https://bitbucket.org/sencyai/ios_sdks_release.git'
source 'https://github.com/CocoaPods/Specs.git'- Add
use_frameworks!to your target:
target 'YourApp' do
use_frameworks!
# ... other pods
end- Add the post-install hook at the end of your Podfile:
post_install do |installer|
react_native_post_install(
installer,
:mac_catalyst_enabled => false
)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
end
end
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end- Install pods:
cd ios
NO_FLIPPER=1 pod install
cd ..- Add camera permission to
Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is needed for fitness assessments and motion detection</string>Android Setup
- Update your project-level
build.gradle:
buildscript {
ext {
minSdkVersion = 26
// ... other settings
}
}
allprojects {
maven {
url "https://artifacts.sency.ai/artifactory/release/"
}
}- Ensure your app's
build.gradletargets Android API 26+:
android {
compileSdkVersion 36
defaultConfig {
minSdkVersion 26
targetSdkVersion 36
}
}- Pose Estimation Model Selection (v2.0.5+)
The SMKit SDK automatically selects the best pose estimation model based on device capabilities:
- Pro Model - High-end devices for maximum accuracy and detailed pose detection
- Lite Model - Mid-range devices for balanced performance and accuracy
- UltraLite Model - Lower-end devices for smooth real-time performance
This automatic selection ensures optimal performance and accuracy across a wide range of Android devices without requiring manual configuration.
Getting Started
1. Initialize the Library
Call configure() as early as possible in your app (e.g., on app launch):
import { configure } from '@sency/react-native-smkit-ui';
try {
await configure('YOUR_API_KEY');
} catch (error) {
console.error('Failed to configure SMKit UI:', error);
}⚠️ Important: The library will not function until
configure()is called successfully.
2. Request Camera Permissions
Ensure your app has camera permissions granted before starting assessments or workouts:
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
const cameraPermission = await request(
Platform.OS === 'ios'
? PERMISSIONS.IOS.CAMERA
: PERMISSIONS.ANDROID.CAMERA
);
if (cameraPermission === RESULTS.GRANTED) {
// Ready to start assessments/workouts
}Core Features
Assessment Types
| Type | Purpose | Use Case | |------|---------|----------| | Fitness | Comprehensive fitness evaluation | General fitness assessment for all levels | | Body360 | Full-body movement and posture analysis | Preventative health screening | | Strength | Core and endurance strength testing | Evaluate strength capabilities | | Cardio | Cardiovascular capacity assessment | Assess aerobic fitness | | Custom | Custom assessment (provided by Sency) | Specialized evaluations |
Workout Configuration
Customize workouts with:
- Body Zones: Full Body, Upper Body, Lower Body
- Difficulty: Low, Mid, High
- Duration: Short, Long
- Week Number: For multi-week programs
API Reference
Core Methods
configure(apiKey: string): Promise<void>
Initialize the SMKit UI library with your API key.
import { configure } from '@sency/react-native-smkit-ui';
await configure('YOUR_API_KEY');startAssessment(type, showSummary, userData, forceShowUserDataScreen, customAssessmentID, modifications): Promise<{ summary: string; didFinish: boolean }>
Start a fitness assessment.
import { startAssessment, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
const userData = new SMWorkoutLibrary.UserData(
SMWorkoutLibrary.Gender.Other,
35,
'[email protected]'
);
const result = await startAssessment(
SMWorkoutLibrary.AssessmentTypes.Fitness,
true,
userData,
false,
'',
null
);Parameters:
type- The assessment type (Fitness,Body360,Strength,Cardio,Custom)showSummary- Display summary after completionuserData- OptionalSMWorkoutLibrary.UserData; passnullwhen not neededforceShowUserDataScreen- Forces the user data screen even when user data is providedcustomAssessmentID- Custom assessment identifier, or an empty stringmodifications- Optional JSON string with exercise feedback parameter modifications
startWorkoutProgram(config: SMWorkoutLibrary.WorkoutConfig, modifications: string | null): Promise<{ summary: string; didFinish: boolean }>
Start a workout program with customization options.
import { startWorkoutProgram, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
const config = new SMWorkoutLibrary.WorkoutConfig(
1,
SMWorkoutLibrary.BodyZone.FullBody,
SMWorkoutLibrary.WorkoutDifficulty.MidDifficulty,
SMWorkoutLibrary.WorkoutDuration.Short,
SMWorkoutLibrary.Language.English,
'program-123',
{
shortIntro: true,
phonePosition: SMWorkoutLibrary.PhonePosition.Floor,
}
);
const result = await startWorkoutProgram(config, null);startCustomAssessment(assessment, userData, forceShowUserDataScreen, showSummary, modifications): Promise<{ summary: string; didFinish: boolean }>
Start a custom assessment (assessment configured by Sency for your specific needs).
import { startCustomAssessment, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
const assessment = new SMWorkoutLibrary.SMWorkout(
'assessment-123',
'Mobility Check',
null,
null,
[],
null,
null,
null
);
const result = await startCustomAssessment(assessment, null, false, true, null);Configuration Methods
setPauseTypes(types: PauseType[]): Promise<void>
Configure which buttons appear in the pause menu during workouts and assessments.
import { setPauseTypes, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
await setPauseTypes([
SMWorkoutLibrary.PauseType.Resume,
SMWorkoutLibrary.PauseType.Skip,
SMWorkoutLibrary.PauseType.Quit
]);Parameters:
types- Array of pause button types to display. Available types:Resume,Skip,StartOver,Quit,Rest,Switch
setSkeletonSettings(config: SkeletonConfig): Promise<void>
Customize the skeleton visualization style during exercises.
import { setSkeletonSettings, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
await setSkeletonSettings({
preset: SMWorkoutLibrary.SkeletonPreset.NeonGlow,
connectionStyle: SMWorkoutLibrary.SkeletonConnectionStyle.Solid,
dotsOpacity: 1,
connectionsOpacity: 0.8
});setInstructionVideoConfig(config: VideoInstructionConfig): Promise<void>
Configure how instruction videos are displayed.
import { setInstructionVideoConfig } from '@sency/react-native-smkit-ui';
await setInstructionVideoConfig({
displayMode: 'mediumCycle',
mediumSizeCycles: 2
});setAllowAudioMixing(enabled: boolean): Promise<void>
Allow SDK audio to mix with external app audio. Supported on iOS and Android native SDKs that expose the control.
import { setAllowAudioMixing } from '@sency/react-native-smkit-ui';
await setAllowAudioMixing(true);setShowExternalAudioControl(enabled: boolean): Promise<void>
Show an in-session button to switch audio source. Supported on iOS and Android native SDKs that expose the control.
import { setShowExternalAudioControl } from '@sency/react-native-smkit-ui';
await setShowExternalAudioControl(true);setAccuratePoseEstimation(enabled: boolean): Promise<void>
Enable higher-accuracy pose estimation at the cost of performance. (iOS only)
import { setAccuratePoseEstimation } from '@sency/react-native-smkit-ui';
await setAccuratePoseEstimation(true);Advanced SDK controls
These setters are exported directly from the React Native package and return Promise<void> unless noted. Platform-specific methods validate their input and resolve as a no-op on unsupported platforms.
| Method | Purpose |
|--------|---------|
| setColorTheme(theme) | Applies a native SDK color theme. |
| setPlayPhoneCalibrationAudio(enabled) | Enables phone calibration audio. |
| setPlayBodyCalibrationAudio(enabled) | Enables body calibration audio. |
| setStartTimerOnFirstActivity(enabled) | Starts exercise timers on first detected activity. |
| setWorkoutContinuationTimerDuration(seconds) | Sets the continuation countdown duration. |
| setPhoneMovementCountPreventionEnabled(enabled) | Prevents counting while phone movement is detected. |
| setVariationMismatchFeedbackEnabled(enabled) | Enables variation mismatch feedback. |
| setUseDefaultGuidanceMode(enabled) | Lets native SDK defaults drive guidance mode. |
| setGuidanceDebugLogging(enabled) | Enables native guidance debug logging where supported. |
| setEnableButtonTutorial(enabled) | Shows the button tutorial overlay. |
| setButtonTutorialCompletionAudioUri(uri) | Sets optional tutorial completion audio. |
| setShowRowingPhoneCalibration(enabled) | iOS rowing phone calibration control; Android no-op. |
| setFeedbacksUIToExclude(values) | Hides selected native feedback types from UI. |
| setExcludedFeedbacks(values) | Excludes selected feedbacks where supported. |
| setConfigString(value) | Android native flat config string; iOS no-op. |
| clearAdaptiveRomCache() | Clears adaptive ROM cache where supported. |
| quitWorkout() | Quits the active workout where supported. |
| pauseSDK() / resumeSDK() | iOS active-workout pause and resume; Android no-op. |
| getSupportedMovements() | iOS supported movement names; Android returns an empty array. |
| getExerciseType(detector) | iOS exercise type lookup; Android returns an empty string. |
| setPoseModelChoice(choice) | Android pose model choice before configure; iOS no-op. |
import {
setColorTheme,
setPlayPhoneCalibrationAudio,
setPlayBodyCalibrationAudio,
setPhoneMovementCountPreventionEnabled,
setPoseModelChoice,
SMWorkoutLibrary,
} from '@sency/react-native-smkit-ui';
await setColorTheme(SMWorkoutLibrary.ColorTheme.Green);
await setPlayPhoneCalibrationAudio(true);
await setPlayBodyCalibrationAudio(true);
await setPhoneMovementCountPreventionEnabled(true);
await setPoseModelChoice(SMWorkoutLibrary.PoseModelChoice.AdaptiveChoice);Interactive Talk to Jinni is intentionally not exposed by this React Native SDK.
Advanced custom workout options
SMExercise, SMAssessmentExercise, and WorkoutConfig keep their existing constructor arguments and accept optional trailing options objects for newer native SDK features.
import { startCustomWorkout, SMWorkoutLibrary } from '@sency/react-native-smkit-ui';
const exercise = new SMWorkoutLibrary.SMExercise(
'Squat',
45,
'squat_instruction.mp4',
'squat_intro.mp3',
[
SMWorkoutLibrary.UIElement.RepsCounter,
SMWorkoutLibrary.UIElement.Skeleton,
SMWorkoutLibrary.UIElement.CountdownTimer,
],
'SquatRegular',
null,
new SMWorkoutLibrary.SMScoringParams(
SMWorkoutLibrary.ScoringType.Reps,
null,
null,
12,
null,
null
),
{
shortIntro: true,
guidanceMode: true,
guidanceVideoSegments: {
introFreeze: SMWorkoutLibrary.GuidanceVideoSegment.freeze(1.2),
demoLoop: SMWorkoutLibrary.GuidanceVideoSegment.play(2.0, 6.5),
},
playPreExerciseCountdown: true,
playSoundOnEachRep: true,
playRepMilestoneVoice: true,
repMilestoneInterval: 5,
adaptiveRomFeedbackEnabled: true,
adaptiveRomWarmupReps: 3,
stretchSetConfig: new SMWorkoutLibrary.StretchSetConfig(3, 20, {
restSecondsBetweenStretches: 5,
}),
}
);
const continuation = new SMWorkoutLibrary.WorkoutContinuation(
'continue_unlock.mp3',
[exercise],
'continue_intro.mp3'
);
const workout = new SMWorkoutLibrary.SMWorkout(
'workout-123',
'Strength Builder',
null,
null,
[exercise],
null,
null,
null,
continuation
);
await startCustomWorkout(workout, null);The supported exercise options include shortIntro, quickMotionParams, rowingFeedbackLevel, phonePosition, guidanceMode, useWideAngleCamera, playPreExerciseCountdown, playRepMilestoneVoice, repMilestoneInterval, playSoundOnEachRep, adaptiveRomFeedbackEnabled, adaptiveRomWarmupReps, guidanceVideoSegments, stretchSetConfig, and side.
Examples
Complete Setup Example
import React, { useEffect, useState } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import {
configure,
startAssessment,
startWorkoutProgram,
SMWorkoutLibrary
} from '@sency/react-native-smkit-ui';
export default function FitnessApp() {
const [isConfigured, setIsConfigured] = useState(false);
useEffect(() => {
initializeApp();
}, []);
const initializeApp = async () => {
try {
await configure('YOUR_API_KEY');
setIsConfigured(true);
} catch (error) {
console.error('Configuration failed:', error);
}
};
const handleFitnessAssessment = async () => {
try {
const result = await startAssessment(
SMWorkoutLibrary.AssessmentTypes.Fitness,
true,
null,
false,
'',
null
);
console.log('Assessment completed:', result);
} catch (error) {
console.error('Assessment failed:', error);
}
};
const handleWorkout = async () => {
try {
const config = new SMWorkoutLibrary.WorkoutConfig(
1,
SMWorkoutLibrary.BodyZone.FullBody,
SMWorkoutLibrary.WorkoutDifficulty.MidDifficulty,
SMWorkoutLibrary.WorkoutDuration.Short,
SMWorkoutLibrary.Language.English,
'program-123'
);
const result = await startWorkoutProgram(config, null);
console.log('Workout completed:', result);
} catch (error) {
console.error('Workout failed:', error);
}
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
onPress={handleFitnessAssessment}
disabled={!isConfigured}
>
<Text>Start Fitness Assessment</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={handleWorkout}
disabled={!isConfigured}
>
<Text>Start Workout</Text>
</TouchableOpacity>
</View>
);
}Body360 Assessment Example
const startBody360Assessment = async () => {
try {
const result = await startAssessment(
SMWorkoutLibrary.AssessmentTypes.Body360,
true,
null,
false,
`user-${Date.now()}`,
null
);
if (result.didFinish) {
console.log('Body360 assessment completed');
console.log('Summary:', result.summary);
}
} catch (error) {
console.error('Body360 assessment error:', error);
}
};Customized Workout Example
const startCustomizedWorkout = async () => {
try {
const config = new SMWorkoutLibrary.WorkoutConfig(
2,
SMWorkoutLibrary.BodyZone.UpperBody,
SMWorkoutLibrary.WorkoutDifficulty.HighDifficulty,
SMWorkoutLibrary.WorkoutDuration.Long,
SMWorkoutLibrary.Language.English,
'program-123',
{ shortIntro: true }
);
const result = await startWorkoutProgram(config, null);
console.log('Workout program completed:', result);
} catch (error) {
console.error('Workout error:', error);
}
};Troubleshooting
"Configuration Failed" Error
Problem: configure() throws an error or returns false.
Solutions:
- Verify your API key is correct
- Check your internet connection
- Ensure the SMKit backend service is available
- Call
configure()before using any other library functions
Camera Permissions Not Granted
Problem: Assessment or workout fails with camera permission error.
Solutions:
- Request camera permissions before starting assessments
- Check that permissions are granted in device settings
- On iOS, verify
NSCameraUsageDescriptionis inInfo.plist - On Android, ensure runtime permissions are requested
iOS Pod Installation Issues
Problem: pod install fails or shows version conflicts.
Solutions:
cd ios
rm -rf Pods
rm Podfile.lock
pod cache clean --all
pod install
cd ..Android Build Failures
Problem: Gradle build fails with native dependency errors.
Solutions:
# Clean Gradle caches
rm -rf ~/.gradle/caches/
# Clean project
cd android
./gradlew clean
cd ..
# Rebuild
npm install
yarn androidMotion Detection Not Working
Problem: Assessment starts but motion detection fails.
Solutions:
- Ensure adequate lighting in the environment
- Position user fully in camera frame
- Verify camera lens is clean
- Check that device camera is not in use by another app
Library Not Initializing
Problem: Features don't work even after calling configure().
Solutions:
- Verify
configure()was called and completed successfully - Check for error messages in console logs
- Ensure you're not calling library methods before
configure()completes - Test with a fresh app start
Additional Resources
- API Documentation - Complete API reference with detailed parameters
- Changelog - Version history and release notes
- Example App - Working demonstration app with source code
Support
Need help?
- Documentation: See API.md for detailed API documentation
- Issues: Check our GitHub Issues
- Email: [email protected]
License
MIT
Repository
- GitHub: sency-ai/smkit-sdk
- NPM Package: @sency/react-native-smkit-ui
