> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# aplicación para iOS

Disponibilidad: las compilaciones de la app para iPhone se distribuyen a través de los canales de Apple cuando están habilitadas para una versión. Las compilaciones de desarrollo local también pueden ejecutarse desde el código fuente.

## Qué hace

* Se conecta a un Gateway mediante WebSocket (LAN o tailnet).
* Expone capacidades del nodo: Canvas, captura de pantalla, captura de cámara, ubicación, modo de conversación y activación por voz.
* Recibe comandos `node.invoke` e informa eventos de estado del nodo.
* Explora el área de trabajo del agente seleccionado en modo de solo lectura desde la superficie Agents (Files): navegación por directorios, vistas previas de texto con resaltado de sintaxis, vistas previas de imágenes y exportación mediante hoja para compartir. Sin operaciones de escritura; las vistas previas tienen un límite de tamaño impuesto por el gateway.
* Mantiene una pequeña caché sin conexión de solo lectura de sesiones de chat y transcripciones recientes por cada gateway emparejado: las aperturas en frío muestran de inmediato la última transcripción conocida y se actualizan cuando el gateway responde, los chats recientes siguen siendo explorables mientras no hay conexión, y restablecer/olvidar purga la caché local protegida.
* Encola los mensajes de texto enviados sin conexión en una bandeja de salida duradera por gateway (hasta 50): las burbujas en cola aparecen en la transcripción, se envían en orden al reconectar con reintentos idempotentes, permanecen de forma duradera hasta que el historial canónico confirma el envío, reintentan con retroceso antes de mostrar una acción de reintentar/eliminar, y caducan en lugar de enviarse tras 48 horas sin conexión; restablecer/olvidar borra la cola junto con la caché.
* Reproduce mensajes del asistente bajo demanda: mantén pulsado un mensaje en Chat y elige **Escuchar**. La app reproduce clips `tts.speak` admitidos por el gateway con el proveedor TTS configurado y recurre a voz en el dispositivo cuando el audio del gateway no está disponible o no se puede reproducir. La reproducción se detiene al cambiar de sesión o al pasar a segundo plano.

## Requisitos

* Gateway ejecutándose en otro dispositivo (macOS, Linux o Windows mediante WSL2).
* Ruta de red:
  * Misma LAN mediante Bonjour, **o**
  * Tailnet mediante DNS-SD unicast (dominio de ejemplo: `openclaw.internal.`), **o**
  * Host/puerto manual (alternativa).

## Inicio rápido (emparejar + conectar)

1. Inicia un Gateway autenticado con una ruta que tu teléfono pueda alcanzar. Tailscale
   Serve es la ruta remota recomendada:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw gateway --port 18789 --tailscale serve
```

Para una configuración de confianza en la misma LAN, usa un `gateway.bind: "lan"`
autenticado en su lugar. El bind local loopback predeterminado no es alcanzable desde un teléfono. Si el
Gateway aún no se ha configurado, ejecuta primero `openclaw onboard` para que la creación
del código de configuración tenga una ruta de autenticación con token o contraseña.

2. Abre la [Interfaz de control](/es/web/control-ui), selecciona **Nodes** y haz clic en
   **Pair mobile device** en la tarjeta **Devices**.

3. En la app iOS, abre **Settings** -> **Gateway**, escanea el código QR (o pega
   el código de configuración) y conéctate.

   Si el código de configuración contiene rutas LAN y Tailscale Serve, la app
   las prueba en orden y guarda el primer endpoint alcanzable.

4. La app oficial se conecta automáticamente. Si **Devices** muestra una solicitud
   pendiente, revisa su rol y ámbitos antes de aprobarla.

El complemento de Apple Watch no tiene una aprobación de emparejamiento de OpenClaw separada.
Empareja el Watch con el iPhone en la app Watch de Apple, instala OpenClaw desde
**Watch app -> My Watch -> Available Apps** y luego abre OpenClaw una vez en ambos
dispositivos. OpenClaw sigue inmediatamente los cambios de emparejamiento e instalación de Apple Watch;
la aprobación de dispositivo del Gateway cubre el nodo del iPhone.

El botón de la Interfaz de control requiere una sesión ya emparejada con `operator.admin`.
Como alternativa desde la terminal, elige un gateway descubierto en la app iOS (o habilita
Manual Host e introduce host/puerto) y luego aprueba la solicitud en el host del Gateway:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw devices list
openclaw devices approve <requestId>
```

Si la app reintenta el emparejamiento con detalles de autenticación cambiados (rol/ámbitos/clave pública), la solicitud pendiente anterior se reemplaza y se crea un nuevo `requestId`. Ejecuta `openclaw devices list` de nuevo antes de aprobar.

Opcional: si el nodo iOS siempre se conecta desde una subred estrictamente controlada, puedes optar por la autoaprobación inicial del nodo con CIDR explícitos o IP exactas:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  gateway: {
    nodes: {
      pairing: {
        autoApproveCidrs: ["192.168.1.0/24"],
      },
    },
  },
}
```

Esto está deshabilitado de forma predeterminada. Se aplica solo al emparejamiento nuevo con `role: node` y sin ámbitos solicitados. El emparejamiento de operador/navegador y cualquier cambio de rol, ámbito, metadatos o clave pública sigue requiriendo aprobación manual.

5. Verifica la conexión:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw nodes status
openclaw gateway call node.list --params "{}"
```

## Push respaldado por relay para compilaciones oficiales

Las compilaciones iOS distribuidas oficialmente usan un relay push externo en lugar de publicar el token APNs sin procesar en el gateway. Las compilaciones oficiales de App Store del canal de lanzamiento público usan el relay alojado en `https://ios-push-relay.openclaw.ai`; esta URL base está codificada para la distribución de App Store y no lee ninguna sobrescritura.

Los despliegues de relay personalizados requieren una ruta de compilación/despliegue de iOS deliberadamente separada cuya URL de relay coincida con la URL de relay del gateway. El canal de lanzamiento de App Store nunca acepta una URL de relay personalizada. Si usas una compilación con relay personalizado, configura la URL de relay correspondiente del gateway:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  gateway: {
    push: {
      apns: {
        relay: {
          baseUrl: "https://relay.example.com",
        },
      },
    },
  },
}
```

Cómo funciona el flujo:

* La app iOS se registra con el relay usando App Attest y un JWS de transacción de app de StoreKit.
* El relay devuelve un identificador de relay opaco más una concesión de envío con alcance de registro.
* La app iOS obtiene la identidad del gateway emparejado (`gateway.identity.get`) y la incluye en el registro del relay, de modo que el registro respaldado por relay se delega a ese gateway específico.
* La app reenvía ese registro respaldado por relay al gateway emparejado con `push.apns.register`.
* El gateway usa ese identificador de relay almacenado para `push.test`, activaciones en segundo plano y avisos de activación.
* Si la app se conecta posteriormente a otro gateway o a una compilación con una URL base de relay diferente, actualiza el registro del relay en lugar de reutilizar la vinculación anterior.

Lo que el gateway **no** necesita para esta ruta: ningún token de relay de todo el despliegue, ninguna clave APNs directa para envíos oficiales de App Store respaldados por relay.

Flujo esperado del operador:

1. Instala la app iOS oficial.
2. Opcional: configura `gateway.push.apns.relay.baseUrl` en el gateway solo cuando uses una compilación con relay personalizado deliberadamente separada.
3. Empareja la app con el gateway y deja que termine de conectarse.
4. La app publica `push.apns.register` una vez que tiene un token APNs, la sesión del operador está conectada y el registro del relay se completa correctamente.
5. Después de eso, `push.test`, las activaciones de reconexión y los avisos de activación pueden usar el registro almacenado respaldado por relay.

## Balizas de actividad en segundo plano

Cuando iOS activa la app por un push silencioso, una actualización en segundo plano o un evento de ubicación significativa, la app intenta una reconexión breve del nodo y luego llama a `node.event` con `event: "node.presence.alive"`. El gateway registra esto como `lastSeenAtMs`/`lastSeenReason` en los metadatos del nodo/dispositivo emparejado solo después de conocer la identidad autenticada del dispositivo nodo.

La app considera que una activación en segundo plano se registró correctamente solo cuando la respuesta del gateway incluye `handled: true`. Los gateways más antiguos pueden confirmar `node.event` con `{ "ok": true }`; esa respuesta es compatible, pero no cuenta como una actualización duradera de último visto.

Nota de compatibilidad:

* `OPENCLAW_APNS_RELAY_BASE_URL` sigue funcionando como sobrescritura temporal de entorno para el gateway (`gateway.push.apns.relay.baseUrl` es la ruta que prioriza la configuración).
* El modo push de la compilación de lanzamiento de App Store codifica el host de relay alojado y nunca lee una sobrescritura de URL de relay: la variable de entorno de tiempo de compilación `OPENCLAW_PUSH_RELAY_BASE_URL` solo afecta a los modos de compilación iOS locales/sandbox.

## Flujo de autenticación y confianza

El relay existe para aplicar dos restricciones que APNs directo en el gateway no puede proporcionar para compilaciones oficiales de iOS:

* Solo las compilaciones iOS genuinas de OpenClaw distribuidas mediante Apple pueden usar el relay alojado.
* Un gateway solo puede enviar pushes respaldados por relay para dispositivos iOS que se emparejaron con ese gateway específico.

Salto por salto:

1. `iOS app -> gateway`: la app se empareja con el gateway mediante el flujo normal de autenticación del Gateway, lo que le da una sesión de nodo autenticada más una sesión de operador autenticada. La sesión de operador llama a `gateway.identity.get`.
2. `iOS app -> relay`: la app llama a los endpoints de registro del relay por HTTPS con prueba de App Attest más un JWS de transacción de app de StoreKit. El relay valida el ID del bundle, la prueba de App Attest y la prueba de distribución de Apple, y exige la ruta de distribución oficial/producción; esto es lo que bloquea que compilaciones locales de Xcode/dev usen el relay alojado, ya que una compilación local no puede satisfacer la prueba oficial de distribución de Apple.
3. `gateway identity delegation`: antes del registro del relay, la app obtiene la identidad del gateway emparejado desde `gateway.identity.get` y la incluye en la carga útil de registro del relay. El relay devuelve un identificador de relay y una concesión de envío con alcance de registro delegada a esa identidad de gateway.
4. `gateway -> relay`: el gateway almacena el identificador de relay y la concesión de envío de `push.apns.register`. En `push.test`, activaciones de reconexión y avisos de activación, el gateway firma la solicitud de envío con su propia identidad de dispositivo; el relay verifica tanto la concesión de envío almacenada como la firma del gateway frente a la identidad de gateway delegada desde el registro. Otro gateway no puede reutilizar ese registro almacenado, incluso si de algún modo obtiene el identificador.
5. `relay -> APNs`: el relay posee las credenciales APNs de producción y el token APNs sin procesar de la compilación oficial. El gateway nunca almacena el token APNs sin procesar para compilaciones oficiales respaldadas por relay; el relay envía el push final a APNs en nombre del gateway emparejado.

Por qué se creó este diseño: para mantener las credenciales APNs de producción fuera de los gateways de los usuarios, evitar almacenar tokens APNs sin procesar de compilaciones oficiales en el gateway, permitir el uso del relay alojado solo para compilaciones iOS oficiales de OpenClaw y evitar que un gateway envíe pushes de activación a dispositivos iOS propiedad de otro gateway.

Las compilaciones locales/manuales siguen usando APNs directo. Si pruebas esas compilaciones sin el relay, el gateway sigue necesitando credenciales APNs directas:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
export OPENCLAW_APNS_TEAM_ID="TEAMID"
export OPENCLAW_APNS_KEY_ID="KEYID"
export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"
```

Estas son variables de entorno de runtime del host del gateway, no ajustes de Fastlane. `apps/ios/fastlane/.env` solo almacena autenticación de App Store Connect, como `APP_STORE_CONNECT_KEY_ID` y `APP_STORE_CONNECT_ISSUER_ID`; no configura la entrega APNs directa para compilaciones iOS locales.

Almacenamiento recomendado en el host del gateway, coherente con otras credenciales de proveedores bajo `~/.openclaw/credentials/`:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
mkdir -p ~/.openclaw/credentials/apns
chmod 700 ~/.openclaw/credentials/apns
mv /path/to/AuthKey_KEYID.p8 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
chmod 600 ~/.openclaw/credentials/apns/AuthKey_KEYID.p8
export OPENCLAW_APNS_PRIVATE_KEY_PATH="$HOME/.openclaw/credentials/apns/AuthKey_KEYID.p8"
```

No confirmes el archivo `.p8` ni lo coloques bajo el checkout del repositorio.

## Rutas de descubrimiento

### Bonjour (LAN)

La app iOS explora `_openclaw-gw._tcp` en `local.` y, cuando está configurado, el mismo dominio de descubrimiento DNS-SD de área amplia. Los gateways de la misma LAN aparecen automáticamente desde `local.`; el descubrimiento entre redes puede usar el dominio de área amplia configurado sin cambiar el tipo de baliza.

### Tailnet (entre redes)

Si mDNS está bloqueado, usa una zona DNS-SD unicast (elige un dominio; ejemplo: `openclaw.internal.`) y DNS dividido de Tailscale. Consulta [Bonjour](/es/gateway/bonjour) para ver el ejemplo de CoreDNS.

### Host/puerto manual

En Settings, habilita **Manual Host** e introduce el host + puerto del gateway (predeterminado `18789`).

## Múltiples gateways

La app mantiene un registro de cada gateway con el que se ha emparejado, para que puedas alternar entre ellos sin volver a emparejar:

* **Configuración -> Gateway** muestra una lista de **Gateways emparejados** con el gateway activo marcado. Toca una entrada para cambiar; la app cierra las sesiones actuales y se reconecta al gateway seleccionado. Aparece un menú de cambio rápido junto a la fila de conexión cuando hay más de un gateway emparejado.
* Las credenciales, las decisiones de confianza TLS, las preferencias por gateway y el historial de chat en caché se almacenan por gateway. Cambiar nunca mezcla el estado entre gateways, y el registro push sigue al gateway activo.
* Desliza un gateway emparejado (o usa su menú contextual) para **Olvidarlo**, lo que elimina sus credenciales, tokens de dispositivo, pin TLS y chats en caché.
* Los gateways descubiertos deben estar visibles en la red para cambiar a ellos; los gateways manuales se reconectan mediante el host y el puerto guardados.

## Lienzo + A2UI

El nodo iOS renderiza un lienzo WKWebView. Usa `node.invoke` para controlarlo:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw nodes invoke --node "iOS Node" --command canvas.navigate --params '{"url":"http://<gateway-host>:18789/__openclaw__/canvas/"}'
```

Notas:

* El host de lienzo del Gateway sirve `/__openclaw__/canvas/` y `/__openclaw__/a2ui/` desde el servidor HTTP del Gateway (el mismo puerto que `gateway.port`, predeterminado `18789`).
* El nodo iOS mantiene el andamiaje integrado como vista predeterminada conectada. `canvas.a2ui.push` y `canvas.a2ui.reset` usan la página A2UI incluida y propiedad de la app.
* Las páginas A2UI remotas del Gateway son solo de renderizado en iOS; las acciones de botones A2UI nativas solo se aceptan desde páginas incluidas y propiedad de la app.
* Vuelve al andamiaje integrado con `canvas.navigate` y `{"url":""}`.

## Relación con Uso de computadora

La app iOS es una superficie de nodo móvil, no un backend de Uso de computadora de Codex. Uso de computadora de Codex y `cua-driver mcp` controlan un escritorio local macOS mediante herramientas MCP; la app iOS expone capacidades de iPhone mediante comandos de nodo de OpenClaw como `canvas.*`, `camera.*`, `screen.*`, `location.*` y `talk.*`.

Los agentes aún pueden operar la app iOS mediante OpenClaw invocando comandos de nodo, pero esas llamadas pasan por el protocolo de nodo del gateway y siguen los límites de primer plano/segundo plano de iOS. Usa [Uso de computadora de Codex](/es/plugins/codex-computer-use) para control de escritorio local y esta página para capacidades de nodo iOS.

### Evaluación / instantánea del lienzo

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw nodes invoke --node "iOS Node" --command canvas.eval --params '{"javaScript":"(() => { const {ctx} = window.__openclaw; ctx.clearRect(0,0,innerWidth,innerHeight); ctx.lineWidth=6; ctx.strokeStyle=\"#ff2d55\"; ctx.beginPath(); ctx.moveTo(40,40); ctx.lineTo(innerWidth-40, innerHeight-40); ctx.stroke(); return \"ok\"; })()"}'
```

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw nodes invoke --node "iOS Node" --command canvas.snapshot --params '{"maxWidth":900,"format":"jpeg"}'
```

## Activación por voz + modo Talk

* La activación por voz y el modo Talk están disponibles en Configuración.
* Talk en tiempo real de OpenAI usa WebRTC propiedad del cliente cuando `talk.realtime.transport` es `webrtc`; una configuración explícita `gateway-relay` sigue siendo propiedad del Gateway. Consulta [Modo Talk](/es/nodes/talk).
* Los nodos iOS compatibles con Talk anuncian la capacidad `talk` y pueden declarar `talk.ptt.start`, `talk.ptt.stop`, `talk.ptt.cancel` y `talk.ptt.once`; el Gateway permite esos comandos push-to-talk de forma predeterminada para nodos confiables compatibles con Talk.
* iOS puede suspender el audio en segundo plano; trata las funciones de voz como de mejor esfuerzo cuando la app no está activa.

## Errores comunes

* `NODE_BACKGROUND_UNAVAILABLE`: trae la app iOS al primer plano (los comandos de lienzo/cámara/pantalla lo requieren).
* `A2UI_HOST_UNAVAILABLE`: no se pudo alcanzar la página A2UI incluida en el WebView de la app; mantén la app en primer plano en la pestaña Pantalla y vuelve a intentarlo.
* El aviso de emparejamiento nunca aparece: ejecuta `openclaw devices list` y aprueba manualmente.
* Watch no muestra estado de iPhone: confirma que el iPhone informe `watchPaired: true`
  y `watchAppInstalled: true` en `watch.status`. Si el emparejamiento es falso, empareja el
  Watch en la app Watch de Apple. Si la instalación es falsa, instala el complemento
  desde **Mi Watch -> Apps disponibles**. Después de cualquiera de los cambios, abre OpenClaw en el
  Watch una vez; la accesibilidad inmediata aún requiere que ambas apps estén en ejecución,
  mientras que las actualizaciones en cola pueden llegar más tarde en segundo plano.
* La reconexión falla después de reinstalar: se borró el token de emparejamiento del Keychain; vuelve a emparejar el nodo.

## Documentación relacionada

* [Emparejamiento](/es/channels/pairing)
* [Descubrimiento](/es/gateway/discovery)
* [Bonjour](/es/gateway/bonjour)
