iOS and Android

Declare microphone and camera permissions for iOS and Android builds — omitting them causes crashes on iOS and silent failures on Android.

iOS and Android builds use the native transport path. All core SDK features — voice conversation, lip sync, actions, emotion, spatial audio, and Vision — work identically on both platforms. The only required implementation work is declaring OS-level permissions for microphone and camera access before your build goes to a device or an app store.

Feature support

Feature
iOS
Android

Voice conversation

✅ Full

✅ Full

Lip sync

✅ Full

✅ Full

Actions

✅ Full

✅ Full

Emotion

✅ Full

✅ Full

Long-Term Memory

✅ Full

✅ Full

Narrative Design

✅ Full

✅ Full

Vision (WebcamVisionFrameSource)

✅ Full

✅ Full

Spatial audio

✅ Full

✅ Full

Unity AudioSource playback

✅ Full

✅ Full

Microphone device selection

✅ Full

✅ Full

Screen share

❌ Not supported

❌ Not supported

Platform
Supported architectures

iOS

arm64 (device), x86_64 (Simulator)

Android

arm64-v8a, armeabi-v7a, x86_64

iOS setup

iOS requires usage description strings before your app can request microphone or camera access. Set these in Project Settings → Player → iOS → Other Settings → Usage Descriptions.

Key
Required when
Recommended description

NSMicrophoneUsageDescription

Always — required for all voice interactions

This app uses your microphone to enable voice conversations with AI training characters.

NSCameraUsageDescription

Only when Vision is enabled

This app uses your camera so the AI character can see and respond to what you show during the simulation.

Runtime permission handling

The SDK does not request microphone permission automatically. Before starting a conversation, your app must have microphone permission granted — if permission is absent when the SDK starts the microphone, it throws InvalidOperationException. Request permission during app initialization, before the first conversation attempt. iOS displays the permission prompt once per permission type — subsequent launches skip the prompt if permission was already granted or denied.

Request permission and check the result before starting a session:

Example: Surgical consultation training on iOS with Vision

A medical school deploys a patient consultation training app on iPad Pros. Residents practice verbal interaction with a Convai patient character. Vision is enabled so the character can acknowledge physical props — anatomical models and procedure reference cards — held up by the resident.

Setup:

  1. In Project Settings → Player → iOS → Other Settings → Usage Descriptions, set:

    • NSMicrophoneUsageDescription: This app uses your microphone to enable voice conversations with AI training characters.

    • NSCameraUsageDescription: This app uses your camera so the AI character can see and respond to what you show during the simulation.

  2. Add WebcamVisionFrameSource to a scene GameObject and assign a ConvaiVisionPublisher.

  3. Standard SDK configuration for voice conversation.

Outcome: On first launch, iOS displays the microphone permission prompt followed by the camera permission prompt. After both are granted, the resident speaks with the character and holds up physical props in view of the iPad camera. The character acknowledges what it sees and responds with clinically appropriate dialogue.

Android setup

Declare required permissions in a custom AndroidManifest.xml at Assets/Plugins/Android/AndroidManifest.xml. If this file does not exist in your project, create it — Unity merges it with the generated manifest at build time.

After building, verify that the permissions appear in the exported AndroidManifest.xml inside the APK or AAB — Unity's manifest merge can sometimes omit entries if the file is malformed.

Runtime permission handling

The SDK does not request microphone permission automatically. Before starting a conversation, your app must have the RECORD_AUDIO runtime permission granted — if permission is absent when the SDK starts the microphone, it throws InvalidOperationException. Call Permission.RequestUserPermission(Permission.Microphone, callbacks) during app initialization and wait for the callback before starting a session. Unlike iOS, Android permits repeated permission requests. After two denials, Android may present a "Don't ask again" option, after which Permission.RequestUserPermission has no effect. Handle this case with in-app guidance directing the user to device Settings.

Example: Field safety compliance drill on Android

A manufacturing company deploys a safety inspector training app on Android tablets issued to production floor staff. The Convai character plays a safety auditor who runs operators through equipment inspection protocols verbally.

Setup:

  1. Add <uses-permission android:name="android.permission.RECORD_AUDIO" /> to Assets/Plugins/Android/AndroidManifest.xml.

  2. Standard SDK configuration — no Vision, no camera permission required.

  3. After building, verify RECORD_AUDIO appears in the exported manifest.

Outcome: On first launch, Android displays the microphone permission prompt. After the user grants access, the Convai character begins the inspection dialogue. Subsequent launches skip the prompt. The app guides users to device Settings if permission was previously denied.

Vision on mobile

WebcamVisionFrameSource functions on both iOS and Android. Add the component to a GameObject in your scene and assign a ConvaiVisionPublisher. The Unity Inspector displays platform-specific warnings if required permissions are absent — address these before building.

On iOS, Vision requires NSCameraUsageDescription in Player Settings — the component calls Application.RequestUserAuthorization(UserAuthorization.WebCam) automatically at runtime to request the permission. On Android, Vision requires android.permission.CAMERA in the manifest — the component calls Permission.RequestUserPermission(Permission.Camera) automatically at runtime. You do not need to request camera permission manually; declaring it in Player Settings (iOS) or the manifest (Android) is sufficient.

When the app moves to the background, the OS suspends microphone capture automatically. Upon returning to the foreground, the SDK resumes capture without developer intervention. Session state follows the reconnection rules defined in your lifecycle configuration.

Troubleshooting

Symptom
Likely cause
Fix

App crashes on first voice attempt (iOS)

NSMicrophoneUsageDescription missing from Player Settings

Add the key in Project Settings → Player → iOS → Other Settings → Usage Descriptions.

App crashes when Vision starts (iOS)

NSCameraUsageDescription missing from Player Settings

Add the key in Project Settings → Player → iOS → Other Settings → Usage Descriptions.

Microphone permission prompt never appears (Android)

RECORD_AUDIO missing from AndroidManifest.xml

Add <uses-permission android:name="android.permission.RECORD_AUDIO" /> to your manifest and verify it appears in the exported APK.

Camera permission prompt never appears on Android (Vision)

CAMERA missing from AndroidManifest.xml

Add <uses-permission android:name="android.permission.CAMERA" /> to your manifest.

Microphone stops working after app is backgrounded

OS suspended capture — expected behavior

The SDK resumes capture automatically on foreground return. No action needed.

iOS prompt does not appear on second launch

User denied on first launch — iOS does not re-prompt

Add in-app messaging directing the user to Settings → Privacy & Security → Microphone to re-enable. Use Application.HasUserAuthorization(UserAuthorization.Microphone) to detect the denied state.

Next steps

Once permissions are declared and tested on a physical device, your iOS and Android builds are ready for distribution. If you are also deploying on XR headsets, those builds have additional Vision requirements.

XR headsetsWebGL

Last updated

Was this helpful?