Skip to content

docs: document iOS Wi-Fi vs Bluetooth-Classic camera transport#17

Merged
gdelataillade merged 5 commits into
mainfrom
docs/ios-wifi-transport
Jul 1, 2026
Merged

docs: document iOS Wi-Fi vs Bluetooth-Classic camera transport#17
gdelataillade merged 5 commits into
mainfrom
docs/ios-wifi-transport

Conversation

@gdelataillade

@gdelataillade gdelataillade commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

What & why

When testing Meta's CameraAccess sample, starting a stream prompts "Join Wi‑Fi Network RB Meta 01SH" — but our example app never did. Root cause: DAT 0.8.0 fills its high‑bandwidth video lease over either Bluetooth Classic (MFi ExternalAccessory) or Wi‑Fi (NEHotspotConfiguration), and the choice is made entirely by the host app's Info.plist + entitlements — there is no runtime switch.

While com.meta.ar.wearable is declared, the SDK uses Bluetooth Classic and never brings up Wi‑Fi — even with the Wi‑Fi entitlements present. Confirmed on-device: removing the ExternalAccessory keys (and adding the HotspotConfiguration / wifi-info entitlements + NSLocalNetworkUsageDescription / NSBonjourServices) switches to the Wi‑Fi path. Wi‑Fi is higher‑bandwidth; Bluetooth Classic needs no prompt and works offline but is lower‑bandwidth.

Transport does not change App Store eligibility — the SDK links ExternalAccessory.framework unconditionally (verified via otool -L + autolink flags on both MWDATCore and MWDATCamera), the same binary-scanner mechanism that rejected the pre‑0.4.0 mock builds over AVFoundation. Combined with Meta's preview-program publishing limit (select partners only until GA), DAT apps can't ship to the public App Store today regardless of transport. Wi‑Fi's advantage is bandwidth.

The plugin's docs previously hard-coded the Bluetooth‑Classic recipe, silently pinning every consumer to BTC and making Wi‑Fi impossible.

Changes

  • Docs — new "Choose your camera transport (Wi‑Fi recommended vs Bluetooth Classic)" section in README, AGENTS.md, and the Claude / Cursor / Copilot consumer guides, each with an accurate transport-neutral App Store note; setup-dat audit now checks for exactly one transport and verifies CODE_SIGN_ENTITLEMENTS is wired into every Runner build config (an .entitlements file is ignored otherwise). Removed the unconditional com.meta.ar.wearable from base Info.plist snippets; external-accessory background-mode mentions (incl. the enableBackgroundStreaming Dart doc comment) are now noted as BTC-only.
  • Example app — switched to Wi‑Fi: new Runner.entitlements, NSLocalNetworkUsageDescription + NSBonjourServices, CODE_SIGN_ENTITLEMENTS wired into all Runner build configs, ExternalAccessory keys commented out with an explanation.
  • CHANGELOG## Unreleased note (the 0.7.0 entry is untouched, so the pana version check stays green).

No plugin code change — transport is 100% host-app config. dart format clean.

Notes

  • Consumers who want Bluetooth Classic (no prompt / offline) follow the documented BTC recipe instead.
  • App Store: transport choice does not affect eligibility (SDK links ExternalAccessory.framework either way; Meta preview-program limit applies until GA). An earlier draft of this description claimed Wi‑Fi removed the MFi blocker — that was wrong and has been corrected here and in the docs.

🤖 Generated with Claude Code

gdelataillade and others added 5 commits June 30, 2026 19:46
DAT 0.8.0 fills its high-bandwidth video lease over either Bluetooth Classic
(MFi ExternalAccessory) or Wi-Fi (NEHotspotConfiguration), chosen entirely by
the host app's Info.plist + entitlements — there is no runtime switch. While
`com.meta.ar.wearable` is declared the SDK uses Bluetooth Classic and never
brings up Wi-Fi; removing it and adding the HotspotConfiguration / wifi-info
entitlements plus NSLocalNetworkUsageDescription / NSBonjourServices switches
to the higher-bandwidth Wi-Fi path, which also sidesteps the MFi App Store
blocker.

- Add a "Choose your camera transport" section (both recipes, Wi-Fi
  recommended) to README, AGENTS, and the Claude/Cursor/Copilot consumer
  guides; update the setup-dat audit to check for one transport.
- Drop the unconditional ExternalAccessory keys from the base Info.plist
  snippets; make `external-accessory` background-mode notes BTC-only,
  including the enableBackgroundStreaming Dart doc comment.
- Switch the example app to Wi-Fi (new Runner.entitlements, Info.plist keys,
  CODE_SIGN_ENTITLEMENTS wired into all Runner build configs).
- CHANGELOG: add an Unreleased note.

No plugin code change — transport is selected purely by host-app config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses PR review feedback. An `.entitlements` file is ignored by Xcode
unless `CODE_SIGN_ENTITLEMENTS` points at it in every Runner build
configuration, so checking the file's contents alone can green-light a setup
where Wi-Fi transport silently fails. The setup-dat audit now inspects
project.pbxproj / `xcodebuild -showBuildSettings` for the wiring (Debug,
Release, Profile) and refuses to pass an unwired/missing file. The README and
AGENTS Wi-Fi recipes note the same — the Xcode capability route wires it
automatically, a hand-created file does not.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The DAT SDK links ExternalAccessory.framework unconditionally (verified via
`otool -L` + LC_LINKER_OPTION autolink flags on both MWDATCore and
MWDATCamera), so switching the app to the Wi-Fi transport does NOT remove that
dependency from the shipped binary — Apple's upload scanner still sees it
(same mechanism that rejected the pre-0.4.0 mock builds over AVFoundation).

Removed the "App-Store-eligible" / "avoids MFi" claims from the transport
docs (README, AGENTS, getting-started, cursor rule, copilot instructions,
CHANGELOG) and replaced them with an accurate transport-neutral note: App
Store eligibility is unaffected by transport (linked EA framework + Meta's
preview-program publishing limit until GA). Wi-Fi's advantage is bandwidth.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two gaps in the transport docs from the prior commits:

1. No migration path for apps already shipping the pre-Wi-Fi Bluetooth
   Classic recipe. Add a "Migrating or switching camera transport" section
   (README + AGENTS, cross-linked from Troubleshooting/Debugging) with the
   exact steps and the CODE_SIGN_ENTITLEMENTS wiring gotcha called out again,
   since that's the part that silently fails.
2. The docs offered the transport choice but never said what to do if one
   isn't working. All human + AI-agent docs (README, AGENTS, the Claude
   skill/command, Cursor rule, Copilot instructions) now state explicitly
   that switching is a config-only change with no plugin/Dart code involved,
   so a broken transport can just be swapped for the other.

Also: setup-dat.md now instructs the agent to ask the user which transport
they prefer on a fresh project instead of silently defaulting to one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Docs-only release for the iOS Wi-Fi/Bluetooth-Classic camera transport
documentation. Bumps all four lockstep version locations (both pubspecs,
both podspecs) and adds the 0.7.1 CHANGELOG entries per doc/MAINTAINERS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@gdelataillade gdelataillade merged commit 666d6de into main Jul 1, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant