> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/plugins-and-integrations/convai-unity-sdk/platform-guides/ios-and-android.md).

# iOS and 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.` |

{% hint style="danger" %}
**Omitting `NSMicrophoneUsageDescription` crashes the app.** iOS raises `NSInvalidArgumentException` when an app attempts microphone access without this key. The crash occurs at runtime on the first conversation attempt and triggers Apple App Store rejection during review. `NSCameraUsageDescription` carries the same crash risk when Vision is enabled.
{% endhint %}

#### 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.

{% hint style="warning" %}
**iOS one-time prompts cannot be re-triggered.** If a user denies microphone permission, iOS will not show the prompt again. Your app must guide the user to **Settings → Privacy & Security → Microphone** to re-enable access manually. Add in-app messaging for this case — for example, detect denied permission via `Application.HasUserAuthorization(UserAuthorization.Microphone)` and display instructions before attempting to start a session.
{% endhint %}

Request permission and check the result before starting a session:

```csharp
using UnityEngine;

public class MicPermissionCheck : MonoBehaviour
{
    private IEnumerator Start()
    {
        if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
        {
            yield return Application.RequestUserAuthorization(UserAuthorization.Microphone);
        }

        if (!Application.HasUserAuthorization(UserAuthorization.Microphone))
        {
            // User denied. Show guidance to re-enable in iOS Settings.
            ShowPermissionDeniedUI();
            yield break;
        }

        // Permission granted — proceed to start the session.
    }

    private void ShowPermissionDeniedUI()
    {
        // Display instructions directing the user to iOS Settings.
    }
}
```

#### 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.

```xml
<!-- Required for all voice interactions -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<!-- Required only when Vision is enabled -->
<uses-permission android:name="android.permission.CAMERA" />
```

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.

{% content-ref url="/pages/86442e40afdd1c7fd12eb8dc8331a0cc75827347" %}
[XR headsets](/api-docs/plugins-and-integrations/convai-unity-sdk/platform-guides/xr-headsets.md)
{% endcontent-ref %}

{% content-ref url="/pages/7b2c74ff6faeac7d9557447799d0496b11e50783" %}
[WebGL](/api-docs/plugins-and-integrations/convai-unity-sdk/platform-guides/webgl.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.convai.com/api-docs/plugins-and-integrations/convai-unity-sdk/platform-guides/ios-and-android.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
