{
  "title": "iOS App (Node)",
  "content": "Availability: internal preview. The iOS app is not publicly distributed yet.\n\n* Connects to a Gateway over WebSocket (LAN or tailnet).\n* Exposes node capabilities: Canvas, Screen snapshot, Camera capture, Location, Talk mode, Voice wake.\n* Receives `node.invoke` commands and reports node status events.\n\n* Gateway running on another device (macOS, Linux, or Windows via WSL2).\n* Network path:\n  * Same LAN via Bonjour, **or**\n  * Tailnet via unicast DNS-SD (example domain: `openclaw.internal.`), **or**\n  * Manual host/port (fallback).\n\n## Quick start (pair + connect)\n\n1. Start the Gateway:\n\n2. In the iOS app, open Settings and pick a discovered gateway (or enable Manual Host and enter host/port).\n\n3. Approve the pairing request on the gateway host:\n\n4. Verify connection:\n\nThe Gateway advertises `_openclaw-gw._tcp` on `local.`. The iOS app lists these automatically.\n\n### Tailnet (cross-network)\n\nIf mDNS is blocked, use a unicast DNS-SD zone (choose a domain; example: `openclaw.internal.`) and Tailscale split DNS.\nSee [Bonjour](/gateway/bonjour) for the CoreDNS example.\n\nIn Settings, enable **Manual Host** and enter the gateway host + port (default `18789`).\n\nThe iOS node renders a WKWebView canvas. Use `node.invoke` to drive it:\n\n* The Gateway canvas host serves `/__openclaw__/canvas/` and `/__openclaw__/a2ui/`.\n* The iOS node auto-navigates to A2UI on connect when a canvas host URL is advertised.\n* Return to the built-in scaffold with `canvas.navigate` and `{\"url\":\"\"}`.\n\n### Canvas eval / snapshot\n\n## Voice wake + talk mode\n\n* Voice wake and talk mode are available in Settings.\n* iOS may suspend background audio; treat voice features as best-effort when the app is not active.\n\n* `NODE_BACKGROUND_UNAVAILABLE`: bring the iOS app to the foreground (canvas/camera/screen commands require it).\n* `A2UI_HOST_NOT_CONFIGURED`: the Gateway did not advertise a canvas host URL; check `canvasHost` in [Gateway configuration](/gateway/configuration).\n* Pairing prompt never appears: run `openclaw nodes pending` and approve manually.\n* Reconnect fails after reinstall: the Keychain pairing token was cleared; re-pair the node.\n\n* [Pairing](/gateway/pairing)\n* [Discovery](/gateway/discovery)\n* [Bonjour](/gateway/bonjour)",
  "code_samples": [
    {
      "code": "2. In the iOS app, open Settings and pick a discovered gateway (or enable Manual Host and enter host/port).\n\n3. Approve the pairing request on the gateway host:",
      "language": "unknown"
    },
    {
      "code": "4. Verify connection:",
      "language": "unknown"
    },
    {
      "code": "## Discovery paths\n\n### Bonjour (LAN)\n\nThe Gateway advertises `_openclaw-gw._tcp` on `local.`. The iOS app lists these automatically.\n\n### Tailnet (cross-network)\n\nIf mDNS is blocked, use a unicast DNS-SD zone (choose a domain; example: `openclaw.internal.`) and Tailscale split DNS.\nSee [Bonjour](/gateway/bonjour) for the CoreDNS example.\n\n### Manual host/port\n\nIn Settings, enable **Manual Host** and enter the gateway host + port (default `18789`).\n\n## Canvas + A2UI\n\nThe iOS node renders a WKWebView canvas. Use `node.invoke` to drive it:",
      "language": "unknown"
    },
    {
      "code": "Notes:\n\n* The Gateway canvas host serves `/__openclaw__/canvas/` and `/__openclaw__/a2ui/`.\n* The iOS node auto-navigates to A2UI on connect when a canvas host URL is advertised.\n* Return to the built-in scaffold with `canvas.navigate` and `{\"url\":\"\"}`.\n\n### Canvas eval / snapshot",
      "language": "unknown"
    },
    {
      "code": "",
      "language": "unknown"
    }
  ],
  "headings": [
    {
      "level": "h2",
      "text": "What it does",
      "id": "what-it-does"
    },
    {
      "level": "h2",
      "text": "Requirements",
      "id": "requirements"
    },
    {
      "level": "h2",
      "text": "Quick start (pair + connect)",
      "id": "quick-start-(pair-+-connect)"
    },
    {
      "level": "h2",
      "text": "Discovery paths",
      "id": "discovery-paths"
    },
    {
      "level": "h3",
      "text": "Bonjour (LAN)",
      "id": "bonjour-(lan)"
    },
    {
      "level": "h3",
      "text": "Tailnet (cross-network)",
      "id": "tailnet-(cross-network)"
    },
    {
      "level": "h3",
      "text": "Manual host/port",
      "id": "manual-host/port"
    },
    {
      "level": "h2",
      "text": "Canvas + A2UI",
      "id": "canvas-+-a2ui"
    },
    {
      "level": "h3",
      "text": "Canvas eval / snapshot",
      "id": "canvas-eval-/-snapshot"
    },
    {
      "level": "h2",
      "text": "Voice wake + talk mode",
      "id": "voice-wake-+-talk-mode"
    },
    {
      "level": "h2",
      "text": "Common errors",
      "id": "common-errors"
    },
    {
      "level": "h2",
      "text": "Related docs",
      "id": "related-docs"
    }
  ],
  "url": "llms-txt#ios-app-(node)",
  "links": []
}