This guide will walk you through the installation and configuration of the WebView component for integrating KinesteX plans and workouts into your app.
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.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
Add the following keys for camera and microphone usage:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for video streaming.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access is required for video streaming.</string>
Plan Category (key: planC) |
---|
Strength |
Cardio |
Rehabilitation |
Weight Management |
const postData = {
// REQUIRED
userId: 'YOUR USER ID',
company: 'YOUR COMPANY', // contact KinesteX
key: 'YOUR KEY', // contact KinesteX
planC: 'Cardio',
// OPTIONAL
age: 50,
height: 150, // in cm
weight: 200, // in kg
gender: 'Male'
};
Currently supported communication is via HTTP postMessages.
When presenting iframe, share the data in the following way:
useEffect(() => {
if (showWebView && iframeRef.current) {
// Ensure the iframe is loaded before posting the message
iframeRef.current.onload = () => {
iframeRef.current.contentWindow.postMessage(postData, '*'); // Current post message source target, we will make it more secure later
};
}
}, [showWebView]);
To listen to user events:
const handleMessage = (event) => {
try {
if (event.data) {
const message = JSON.parse(event.data);
console.log('Received data:', message); // Log the received data
if (message.type === 'finished_workout') {
console.log('Received data:', message.data);
}
if (message.type === 'exit_kinestex') {
toggleWebView();
}
if (message.type === 'error_occured') {
console.log('Received data:', message.data);
toggleWebView();
}
if (message.type === 'exercise_completed') {
console.log('Received data:', message.data);
}
} else {
console.log('Received empty message'); // Log if the message is empty
}
} catch (e) {
console.error('Could not parse JSON message from WebView:', e);
}
};
useEffect(() => {
const handleWindowMessage = (event) => {
handleMessage(event);
};
window.addEventListener('message', handleWindowMessage);
return () => {
window.removeEventListener('message', handleWindowMessage);
};
}, [toggleWebView]);
Message Types in handleMessage function:
The core of the handleMessage
function is a switch statement that checks the type
property of the parsed message. Each case corresponds to a different type of action or event that occurred in the KinesteX SDK.
Available data types:
Type | Data | Description |
---|---|---|
kinestex_launched |
Format: dd mm yyyy hours:minutes:seconds |
When a user has launched KinesteX |
exit_kinestex |
Format: date: dd mm yyyy hours:minutes:seconds , time_spent: number |
Logs when a user clicks on exit button, requesting dismissal of KinesteX and sending how much time a user has spent totally in seconds since launch |
plan_unlocked |
Format: title: String, date: date and time |
Logs when a workout plan is unlocked by a user |
workout_opened |
Format: title: String, date: date and time |
Logs when a workout is opened by a user |
workout_started |
Format: title: String, date: date and time |
Logs when a workout is started. |
error_occurred |
Format: data: string |
Logs when a significant error has occurred. For example, a user has not granted access to the camera |
exercise_completed |
Format: time_spent: number , repeats: number , calories: number , exercise: string , mistakes: [string: number] |
Logs everytime a user finishes an exercise |
total_active_seconds |
Format: number |
Logs every 5 seconds and counts the number of active seconds a user has spent working out. This value is not sent when a user leaves camera tracking area |
left_camera_frame |
Format: number |
Indicates that a user has left the camera frame. The data sent is the current number of total_active_seconds |
returned_camera_frame |
Format: number |
Indicates that a user has returned to the camera frame. The data sent is the current number of total_active_seconds |
workout_overview |
Format: workout: string ,total_time_spent: number , total_repeats: number , total_calories: number , percentage_completed: number , total_mistakes: number |
Logged when a user finishes the workout with a complete short summary of the workout |
exercise_overview |
Format: [exercise_completed] |
Returns a log of all exercises and their data (exercise_completed data is defined 5 lines above) |
workout_completed |
Format: 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) |
Format: number |
Represents a number of days a user has been opening KinesteX |
total_workouts (Coming soon) |
Format: number |
Represents a number of workouts a user has done since start of using KinesteX |
workout_efficiency (Coming soon) |
Format: number |
Represents the level of intensivity a person has done the workout with. An average level of workout efficiency is 0.5, which represents an average time a person should complete the workout for at least 80% within a specific timeframe. For example, if on average people complete workout X in 15 minutes, but a person Y has completed the workout in 12 minutes, they will have a higher workout_efficiency number |
return (
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
{!showWebView && <button onClick={toggleWebView}>Open WebView</button>} {/* CUSTOM BUTTON TO LAUNCH KINESTEX */}
{showWebView && (
<div style={{ position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', zIndex: '0' }}>
<iframe
ref={iframeRef}
src="https://kinestex.vercel.app/"
frameBorder="0"
allow="camera; microphone; autoplay"
sandbox="allow-same-origin allow-scripts"
allowFullScreen={true}
javaScriptEnabled={true}
style={{ width: '100%', height: '100%' }}
></iframe>
</div>
)}
</div>
);
See App.js for demo code
If you have any questions contact: help@kinestex.com