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.invokee 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.speakadmitidos 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)
- Inicia un Gateway autenticado con una ruta que tu teléfono pueda alcanzar. Tailscale Serve es la ruta remota recomendada:
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.
- Abre la Interfaz de control, selecciona Nodes y haz clic en Pair mobile device en la tarjeta Devices.
- 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.
- La app oficial se conecta automáticamente. Si Devices muestra una solicitud pendiente, revisa su rol y ámbitos antes de aprobarla.
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:
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:
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.
- Verifica la conexión:
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 enhttps://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:
- 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.
- Instala la app iOS oficial.
- Opcional: configura
gateway.push.apns.relay.baseUrlen el gateway solo cuando uses una compilación con relay personalizado deliberadamente separada. - Empareja la app con el gateway y deja que termine de conectarse.
- La app publica
push.apns.registeruna vez que tiene un token APNs, la sesión del operador está conectada y el registro del relay se completa correctamente. - 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 anode.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_URLsigue funcionando como sobrescritura temporal de entorno para el gateway (gateway.push.apns.relay.baseUrles 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_URLsolo 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.
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 agateway.identity.get.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.gateway identity delegation: antes del registro del relay, la app obtiene la identidad del gateway emparejado desdegateway.identity.gety 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.gateway -> relay: el gateway almacena el identificador de relay y la concesión de envío depush.apns.register. Enpush.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.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.
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/:
.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 para ver el ejemplo de CoreDNS.
Host/puerto manual
En Settings, habilita Manual Host e introduce el host + puerto del gateway (predeterminado18789).
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. Usanode.invoke para controlarlo:
- El host de lienzo del Gateway sirve
/__openclaw__/canvas/y/__openclaw__/a2ui/desde el servidor HTTP del Gateway (el mismo puerto quegateway.port, predeterminado18789). - El nodo iOS mantiene el andamiaje integrado como vista predeterminada conectada.
canvas.a2ui.pushycanvas.a2ui.resetusan 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.navigatey{"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 ycua-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 para control de escritorio local y esta página para capacidades de nodo iOS.
Evaluación / instantánea del lienzo
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.transporteswebrtc; una configuración explícitagateway-relaysigue siendo propiedad del Gateway. Consulta Modo Talk. - Los nodos iOS compatibles con Talk anuncian la capacidad
talky pueden declarartalk.ptt.start,talk.ptt.stop,talk.ptt.cancelytalk.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 listy aprueba manualmente. - Watch no muestra estado de iPhone: confirma que el iPhone informe
watchPaired: trueywatchAppInstalled: trueenwatch.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.