/KinesteX-SDK-PWA

Integrate Personal AI Fitness Trainer in your app in minutes

Primary LanguageJavaScript

This guide will walk you through the installation and configuration of the WebView component for integrating KinesteX plans and workouts into your app.

Configuration

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.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />

Info.plist

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>

Available categories to sort plans (param key is planC):

Plan Category (key: planC)
Strength
Cardio
Rehabilitation
Weight Management

Available parameters:

  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'
  };

Communicating with KinesteX:

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

Displaying KinesteX through iframe:

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


Contact:

If you have any questions contact: help@kinestex.com