# Configuration

Initialize the SDK with your API credentials.

**Step 1: Initialize the SDK**

_Swift (iOS)_
```swift
import KinesteXAIKit

@State var showKinesteX = false // Controls KinesteX SDK visibility
@State var isLoading = false    // Optional: Controls custom loading screen

// Initialize with your API key, company name, and unique user ID
let kinestex = KinesteXAIKit(
    apiKey: "YOUR_API_KEY",
    companyName: "YOUR_COMPANY",
    userId: "unique-user-id"
)

// Optional: UserDetails to customize workout intensity
let user = UserDetails(
    age: 20,
    height: 170,
    weight: 70,
    gender: .Male,
    lifestyle: .Active
)
```

_Kotlin (Android)_
```kotlin
import com.kinestex.kinestexsdkkotlin.KinesteXSDK

// Initialize the SDK in your Application class as early as possible
class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        KinesteXSDK.initialize(
            context = this,
            apiKey = "YOUR_API_KEY",
            companyName = "YOUR_COMPANY",
            userId = "unique-user-id"
        )
    }
}
```

_React Native_
```jsx
// 1. Create a reference to KinesteXSDK component
const kinestexSDKRef = useRef<KinesteXSDKCamera>(null);

// 2. Create postData object to initialize KinesteX session
const postData: IPostData = {
  key: 'YOUR_API_KEY',
  userId: 'YOUR_USER_ID', // unique per user
  company: 'YOUR_COMPANY',
  style: {
    style: 'dark', // 'dark' or 'light'
    loadingBackgroundColor: '000000', // hex without #
  },
  customParameters: {
    // language: 'es' // customize language
  },
  // Optional: UserDetails for workout intensity
  age: 25,
  height: 180, // cm
  weight: 75, // kg
  gender: 'Male',
  lifestyle: Lifestyle.Active,
};

// 3. Handle real-time messages from KinesteX
const handleMessage = (type: string, data: { [key: string]: any }) => {
  switch (type) {
    case 'exit_kinestex':
      console.log('User exited');
      setShowKinesteX(false);
      break;
    case 'plan_unlocked':
      console.log('Plan unlocked:', data);
      break;
    default:
      console.log('Message:', type, data);
      break;
  }
};
```

_Flutter_
```dart
import 'package:kinestex_sdk_flutter/kinestex_sdk.dart';
// Initialize the SDK in your main function as early as possible.
await KinesteXAIFramework.initialize(
  apiKey: "YOUR_API_KEY",
  companyName: "YOUR_COMPANY",
  userId: "unique-user-id",
);
```

_HTML / JavaScript_
```html
// 1. Define the config data to be sent to the iframe
  const postData = {
  userId: "YOUR_USER_ID", // Unique identifier for the user
  company: "YOUR_COMPANY", // Your organization's name from kinestex admin dashboard
  key: "YOUR_API_KEY", // Your API Key from kinestex admin dashboard

  // Optional parameters for customization
  style: "dark", // dark or light theme

  // user related customization
  age: 30, // User's age (optional)
  height: 175, // User's height in cm (optional)
  weight: 70, // User's weight in kg (optional)
  gender: "Female", // Gender (optional)
};

// 2. Sending the messages to the iframe will be done through postMessage API
function sendMessage() {
      if (webView.contentWindow) {
        webView.contentWindow.postMessage(postData, srcURL); // post initial data to start session
      } else {
        setTimeout(() => {
          try {
            webView.contentWindow.postMessage(postData, srcURL); // post initial data to start session
          } catch {
            webView.contentWindow.postMessage(postData, srcURL); // retry sending message
          }
        }, 100);
      }
}
// 3. Whenever you want to display the view:
webView.src = srcURL; // Update this URL for specific features

webView.onload = () => {
    sendMessage();
};

// 4. Handle the loading confirmation received from the iframe to send the initial data once more (iOS specific verification)
window.addEventListener("message", (event) => {
  if (event.origin !== "https://ai.kinestex.com") return; // prevent listening for messages from other sources for security

  const message = JSON.parse(event.data);
  if (message.type === 'kinestex_loaded') {
    sendMessage();
  }
});

```

_React (TypeScript)_
```tsx
// 1. Create a reference to KinesteXSDK component
const kinestexSDKRef = useRef<KinesteXSDKCamera>(null);

// 2. Create postData object to initialize KinesteX session
const postData: IPostData = {
  key: 'YOUR_API_KEY',
  userId: 'YOUR_USER_ID', // unique per user
  company: 'YOUR_COMPANY',
  style: {
    style: 'dark', // 'dark' or 'light'
    loadingBackgroundColor: '000000', // hex without #
  },
  customParameters: {
    // language: 'es' // customize language
  },
  // Optional: UserDetails for workout intensity
  age: 25,
  height: 180, // cm
  weight: 75, // kg
  gender: 'Male',
  lifestyle: Lifestyle.Active,
};

// 3. Handle real-time messages from KinesteX
const handleMessage = (type: string, data: { [key: string]: any }) => {
  switch (type) {
    case 'exit_kinestex':
      console.log('User exited');
      setShowKinesteX(false);
      break;
    case 'plan_unlocked':
      console.log('Plan unlocked:', data);
      break;
    default:
      console.log('Message:', type, data);
      break;
  }
};
```

**Step 2: Register Application Class** — Kotlin (Android)

Register your custom Application class in AndroidManifest.xml:

_AndroidManifest.xml_
```xml
<application
    android:name=".MyApplication"
    ...>
</application>
```

**Step 3: Request Camera Permission** — Kotlin (Android)

Before a user starts a workout, request camera permission at the app level. Your activity or fragment must implement the PermissionHandler interface:

_MainActivity with PermissionHandler_
```kotlin
class MainActivity : AppCompatActivity(), PermissionHandler {

    // Initialize the webview
    private var kinesteXWebView: GenericWebView? = null

    // Optional: Pass user details to adjust exercises and estimate calories
    // Note: User details are only used on the device for customization during the session
    private var userDetails = UserDetails(
        age = 20,
        height = 170,
        weight = 180,
        gender = Gender.MALE,
        lifestyle = Lifestyle.ACTIVE
    )

    // Register permission launcher
    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted: Boolean ->
        // Pass permission result to KinesteX webview
        kinesteXWebView?.handlePermissionResult(isGranted)
    }

    // Override to display system dialog for camera access
    override fun requestCameraPermission() {
        requestPermissionLauncher.launch(Manifest.permission.CAMERA)
    }
}
```

**Step 4: Handle SDK Messages** — Kotlin (Android)

Implement a callback function to handle messages from the SDK:

_Message Handler_
```kotlin
private fun handleWebViewMessage(message: WebViewMessage) {
    when (message) {
        is WebViewMessage.ExitKinestex -> {
            // Dismiss KinesteX view when user clicks exit button
        }
        // Handle other messages
        else -> {
            Log.d("KinesteX", message.toString())
        }
    }
}
```

**Step 2: Request Camera Permission** — Flutter

Request camera permission before launching KinesteX. Ensure you've added the necessary permissions in AndroidManifest.xml and Info.plist. Add the following to your iOS Podfile:

_2.1: ios/Podfile_
```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        ## dart: PermissionGroup.camera
        'PERMISSION_CAMERA=1',
      ]
    end
  end
end
```

_2.2: Request Permission in Dart_
```dart
void _checkCameraPermission() async {
  if (await Permission.camera.request() != PermissionStatus.granted) {
    _showCameraAccessDeniedAlert();
  }
}

void _showCameraAccessDeniedAlert() {
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: const Text("Camera Permission Denied"),
        content: const Text("Camera access is required for this app to function properly."),
        actions: <Widget>[
          TextButton(
            child: const Text("OK"),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ],
      );
    },
  );
}
```

**Step 3: Initialize on App Launch** — Flutter

Initialize KinesteX in your main function for WebView warmup:

_main.dart_
```dart
Future<void> main() async {
  await KinesteXAIFramework.initialize(
    apiKey: YOUR_API_KEY,
    companyName: YOUR_COMPANY_NAME,
    userId: YOUR_USER_ID,
  );

  runApp(
    const MaterialApp(
      home: MyHomePage(),
    ),
  );
}
```

**Step 4: Deinitialize on App Closure** — Flutter

Call dispose when closing the app:

_Dispose Method_
```dart
@override
void dispose() {
  disposeKinesteXAIFramework();
  super.dispose();
}
```

**Step 5: Setup Recommendations** — Flutter

Use a ValueNotifier to manage KinesteX presentation and handle callback messages:

_State Management & Message Handler_
```dart
import 'package:kinestex_sdk_flutter/kinestex_sdk.dart';

// Add a ValueNotifier to manage presentation
ValueNotifier<bool> showKinesteX = ValueNotifier<bool>(false);

// Handle callback messages from KinesteX
void handleWebViewMessage(WebViewMessage message) {
  if (message is ExitKinestex) {
    setState(() {
      showKinesteX.value = false;
    });
  } else {
    print("Message received: ${message.data}");
  }
}
```

---
Source: https://www.kinestex.com/docs/configuration · Index: https://www.kinestex.com/llms.txt
