---
title: Info.plist setup (iOS)
description: Required Info.plist keys for the Extentos iOS SDK — the Meta DAT auth callback URL scheme, external accessory protocol, background modes, and Bluetooth / camera / microphone / speech privacy strings. generateConnectionModule emits them all.
type: reference
platform: ios
vendor: meta
related:
  - /docs/concepts/permissions
  - /docs/sdk/ios/initialization
  - /docs/getting-started/with-agent
---

The Extentos iOS SDK rides on the Meta Wearables Device Access Toolkit (DAT). DAT pairs your phone app with Meta Ray-Ban glasses over an external-accessory channel and hands the auth callback back to your app through a **custom URL scheme**. iOS gates every one of those mechanisms behind an `Info.plist` declaration, so the keys below are required for the SDK to reach the glasses through DAT.

<Callout type="info">
  **Voice apps need almost none of this.** A voice-only app reaches its
  microphone and speaker through the phone's own Bluetooth audio routing, never
  through DAT — so it needs no `MWDAT` dict, no Meta App ID, no URL scheme, and
  none of the accessory keys. It needs the privacy strings its capabilities
  imply (`NSMicrophoneUsageDescription`, `NSSpeechRecognitionUsageDescription`)
  and, for background listening, `UIBackgroundModes: ["audio"]`. It also needs
  the two Extentos keys below — `EXTENTOS_APP_ID` and `EXTENTOSProjectKey` —
  which are not Meta keys: the project key is how a debug build on a real phone
  authenticates to the managed gateway, so an assistant app without it fails
  with `AssistantError.NoApiKey`. Everything else on this page is the
  **camera/display** set. See
  [choose your path](/docs/getting-started/choose-your-path).
</Callout>

> **You don't have to add these by hand.** `generateConnectionModule(platform: "ios")` ([agent-driven path](/docs/getting-started/with-agent)) emits a **complete, ready-to-use `Info.plist` as a generated file** — you apply it verbatim (like the bootstrap), and the *same* file works on the simulator and on real glasses. (iOS has no manifest merge, so the SDK package can't supply these keys itself — the scaffold owns the file instead.) This page documents what it writes and why, so you can audit the result or wire an app manually.
>
> The `Info.plist` requirements below are stable and verified against the current source. Package install: [Install](/docs/sdk/ios/install).

## Required keys

| Key | Purpose |
|---|---|
| `MWDAT` (dict) | Meta Wearables DAT configuration. Holds the DAT integration settings the toolkit reads at startup. |
| `MWDAT` → `DAMEnabled` | **Set explicitly in every app** — `true` only if your capability footprint includes Display. Meta's default when the key is *missing* is `true`, and DAM runs an on-glasses DWA readiness probe on DAT 0.8 that **reaps the device session ~10 s after start** on glasses without the DWA app (every current non-display model) — so a camera/audio app with the key missing or `true` loses its session on real hardware. `generateConnectionModule` emits the correct value from your declared capabilities. |
| `CFBundleURLTypes` | Registers your app's **custom URL scheme** so DAT can deliver the auth callback after the user authorizes the glasses. This is a custom scheme, **not** a universal link. |
| `LSApplicationQueriesSchemes` | Must include `fb-viewapp` so the app can hand off to the Meta View / AI app during pairing. |
| `UISupportedExternalAccessoryProtocols` | Must include `com.meta.ar.wearable` — the External Accessory protocol the glasses speak. Without it iOS won't surface the device to the app. |
| `UIBackgroundModes` | `bluetooth-central`, `bluetooth-peripheral`, and `external-accessory` — keeps the accessory session alive when the app isn't foregrounded. **Add `audio` as well if your assistant must keep listening while the app is backgrounded** — the scaffold does not emit it, because it depends on your app's behaviour rather than its capabilities. A voice-only app needs `audio` and none of the other three. |
| `NSCameraUsageDescription` | Camera privacy string — required for photo / video / frame capture. |
| `NSMicrophoneUsageDescription` | Microphone privacy string — required for audio capture and voice. |
| `NSBluetoothAlwaysUsageDescription` | Bluetooth privacy string — the glasses connect over Bluetooth. |
| `NSSpeechRecognitionUsageDescription` | Speech-recognition privacy string — required for on-device transcription via `SFSpeechRecognizer`. See [`requestSpeechRecognitionAuthorization`](/docs/sdk/ios/initialization). |
| `EXTENTOS_APP_ID` | The Extentos project identity — the generated bootstrap reads it into `config.appId`. Decoupled from the store bundle id, so Android and iOS apps whose store ids differ can share one Extentos project. |
| `EXTENTOSProjectKey` | The account-bound project key — the SDK's gateway auth reads it as the dev-tier Bearer token on non-simulator debug builds. |
| `NSAppTransportSecurity` | A loopback-only exception (`localhost` / `127.0.0.1`) so the debug auto-bind probe can reach the MCP localhost bridge over HTTP. Release builds never hit the probe. |

## Why each one

**`MWDAT` and the custom URL scheme (`CFBundleURLTypes`).** Pairing leaves your app, authorizes in Meta's app, and returns. DAT delivers that return through your registered custom scheme — your app catches it in `.onOpenURL` and forwards it via [`glasses.handleUrl(_:)`](/docs/sdk/ios/initialization). A universal link will **not** work here; DAT expects a custom scheme.

**`LSApplicationQueriesSchemes: fb-viewapp`.** iOS blocks `canOpenURL` / cross-app handoff to schemes you haven't declared. Pairing needs to reach the Meta app, so `fb-viewapp` must be listed.

**`UISupportedExternalAccessoryProtocols: com.meta.ar.wearable`.** The glasses are an MFi external accessory. iOS only exposes accessories whose protocol string the app has declared — omit this and the device is invisible to the SDK.

**`UIBackgroundModes`.** A live glasses session (an open accessory channel over Bluetooth) has to survive the app backgrounding. The scaffold declares `bluetooth-central`, `bluetooth-peripheral`, and `external-accessory` so the connection doesn't drop when the user looks away from the phone.

**Privacy strings.** iOS hard-crashes an app that touches the camera, microphone, Bluetooth, or speech recognition without the matching `NS…UsageDescription`. Each Extentos capability maps to one:

- Camera capture / video / frames → `NSCameraUsageDescription`
- Audio capture, `speak`, voice → `NSMicrophoneUsageDescription`
- Any glasses connection → `NSBluetoothAlwaysUsageDescription`
- `glasses.audio.transcriptions()` (on-device STT) → `NSSpeechRecognitionUsageDescription`

Write copy that names *your* feature, e.g. *"Used to capture photos from your Meta Ray-Ban glasses."* The reviewer and the user both read these.

## See also

- [Permissions model](/docs/concepts/permissions) — the cross-platform view of what each capability needs.
- [Initialization](/docs/sdk/ios/initialization) — wiring the `.onOpenURL` auth handoff and requesting speech authorization.
- [Meta Ray-Ban vendor notes](/docs/vendors/meta) — the toolkit's real capability boundaries.
