iOS-App (Node)

Verfügbarkeit: interne Vorschau. Die iOS-App wird noch nicht öffentlich verteilt.

Was sie kann

  • Verbindet sich per WebSocket mit einem Gateway (LAN oder Tailnet).
  • Stellt Node-Funktionen bereit: Canvas, Bildschirm-Snapshot, Kamera-Aufnahme, Standort, Talk-Modus, Voice Wake.
  • Empfängt node.invoke-Befehle und meldet Node-Status-Events.

Voraussetzungen

  • Gateway läuft auf einem anderen Gerät (macOS, Linux oder Windows via WSL2).
  • Netzwerkpfad:
    • Gleiches LAN via Bonjour, oder
    • Tailnet via Unicast DNS-SD (Beispiel-Domain: openclaw.internal.), oder
    • Manueller Host/Port (Fallback).

Schnellstart (Pairing + Verbindung)

  1. Starte das Gateway:
openclaw gateway --port 18789
  1. Öffne in der iOS-App die Einstellungen und wähle ein entdecktes Gateway (oder aktiviere Manueller Host und gib Host/Port ein).

  2. Genehmige die Pairing-Anfrage auf dem Gateway-Host:

openclaw devices list
openclaw devices approve <requestId>
  1. Verbindung prüfen:
openclaw nodes status
openclaw gateway call node.list --params "{}"

Relay-gestützter Push für offizielle Builds

Offiziell verteilte iOS-Builds nutzen das externe Push-Relay, statt den rohen APNs-Token an das Gateway weiterzugeben.

Gateway-seitige Voraussetzung:

{
  gateway: {
    push: {
      apns: {
        relay: {
          baseUrl: "https://relay.example.com",
        },
      },
    },
  },
}

So funktioniert der Ablauf:

  • Die iOS-App registriert sich beim Relay mittels App Attest und dem App-Receipt.
  • Das Relay gibt ein opakes Relay-Handle plus ein registrierungsbezogenes Send-Grant zurück.
  • Die iOS-App ruft die Gateway-Identität des gepaarten Gateways ab und fügt sie in die Relay-Registrierung ein, sodass die relay-gestützte Registrierung an dieses spezifische Gateway delegiert wird.
  • Die App leitet diese relay-gestützte Registrierung mit push.apns.register an das gepaarte Gateway weiter.
  • Das Gateway nutzt das gespeicherte Relay-Handle für push.test, Hintergrund-Wakes und Wake-Nudges.
  • Die Gateway-Relay-Base-URL muss mit der Relay-URL im offiziellen/TestFlight-iOS-Build übereinstimmen.
  • Wenn die App sich später mit einem anderen Gateway oder einem Build mit anderer Relay-Base-URL verbindet, erneuert sie die Relay-Registrierung, statt die alte Bindung wiederzuverwenden.

Was das Gateway für diesen Pfad nicht braucht:

  • Kein deployment-weites Relay-Token.
  • Kein direkter APNs-Schlüssel für offizielle/TestFlight relay-gestützte Sends.

Erwarteter Operator-Ablauf:

  1. Installiere den offiziellen/TestFlight-iOS-Build.
  2. Setze gateway.push.apns.relay.baseUrl auf dem Gateway.
  3. Paare die App mit dem Gateway und lass die Verbindung abschließen.
  4. Die App veröffentlicht push.apns.register automatisch, nachdem sie ein APNs-Token hat, die Operator-Session verbunden ist und die Relay-Registrierung erfolgreich war.
  5. Danach können push.test, Reconnect-Wakes und Wake-Nudges die gespeicherte relay-gestützte Registrierung verwenden.

Kompatibilitätshinweis:

  • OPENCLAW_APNS_RELAY_BASE_URL funktioniert weiterhin als temporärer Env-Override für das Gateway.

Authentifizierung und Vertrauensfluss

Das Relay existiert, um zwei Einschränkungen durchzusetzen, die direktes APNs-on-Gateway für offizielle iOS-Builds nicht bieten kann:

  • Nur echte OpenClaw-iOS-Builds, die über Apple verteilt werden, können das gehostete Relay nutzen.
  • Ein Gateway kann relay-gestützte Pushes nur für iOS-Geräte senden, die mit diesem spezifischen Gateway gepaart wurden.

Schritt für Schritt:

  1. iOS-App -> Gateway

    • Die App paart sich zuerst über den normalen Gateway-Auth-Flow mit dem Gateway.
    • Das gibt der App eine authentifizierte Node-Session plus eine authentifizierte Operator-Session.
    • Die Operator-Session wird verwendet, um gateway.identity.get aufzurufen.
  2. iOS-App -> Relay

    • Die App ruft die Relay-Registrierungs-Endpoints über HTTPS auf.
    • Die Registrierung enthält App-Attest-Nachweis plus App-Receipt.
    • Das Relay validiert die Bundle-ID, den App-Attest-Nachweis und das Apple-Receipt und verlangt den offiziellen/Produktions-Verteilungsweg.
    • Das ist es, was lokale Xcode/Dev-Builds daran hindert, das gehostete Relay zu nutzen. Ein lokaler Build mag signiert sein, erfüllt aber nicht den offiziellen Apple-Verteilungsnachweis, den das Relay erwartet.
  3. Gateway-Identitätsdelegation

    • Vor der Relay-Registrierung ruft die App die Gateway-Identität des gepaarten Gateways über gateway.identity.get ab.
    • Die App fügt diese Gateway-Identität in den Relay-Registrierungs-Payload ein.
    • Das Relay gibt ein Relay-Handle und ein registrierungsbezogenes Send-Grant zurück, die an diese Gateway-Identität delegiert sind.
  4. Gateway -> Relay

    • Das Gateway speichert das Relay-Handle und Send-Grant von push.apns.register.
    • Bei push.test, Reconnect-Wakes und Wake-Nudges signiert das Gateway die Send-Anfrage mit seiner eigenen Device-Identität.
    • Das Relay verifiziert sowohl das gespeicherte Send-Grant als auch die Gateway-Signatur gegen die delegierte Gateway-Identität aus der Registrierung.
    • Ein anderes Gateway kann diese gespeicherte Registrierung nicht wiederverwenden, selbst wenn es das Handle erlangt.
  5. Relay -> APNs

    • Das Relay besitzt die Produktions-APNs-Credentials und den rohen APNs-Token für den offiziellen Build.
    • Das Gateway speichert niemals den rohen APNs-Token für relay-gestützte offizielle Builds.
    • Das Relay sendet den finalen Push an APNs im Namen des gepaarten Gateways.

Warum dieses Design entwickelt wurde:

  • Um Produktions-APNs-Credentials aus Benutzer-Gateways herauszuhalten.
  • Um die Speicherung roher APNs-Tokens für offizielle Builds auf dem Gateway zu vermeiden.
  • Um die Nutzung des gehosteten Relays nur für offizielle/TestFlight-OpenClaw-Builds zu erlauben.
  • Um zu verhindern, dass ein Gateway Wake-Pushes an iOS-Geräte sendet, die einem anderen Gateway gehören.

Lokale/manuelle Builds bleiben auf direktem APNs. Wenn du solche Builds ohne Relay testest, braucht das Gateway weiterhin direkte APNs-Credentials:

export OPENCLAW_APNS_TEAM_ID="TEAMID"
export OPENCLAW_APNS_KEY_ID="KEYID"
export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"

Discovery-Pfade

Bonjour (LAN)

Das Gateway advertised _openclaw-gw._tcp auf local.. Die iOS-App listet diese automatisch auf.

Tailnet (netzwerkübergreifend)

Falls mDNS blockiert ist, verwende eine Unicast-DNS-SD-Zone (wähle eine Domain; Beispiel: openclaw.internal.) und Tailscale Split DNS. Siehe Bonjour für das CoreDNS-Beispiel.

Manueller Host/Port

Aktiviere in den Einstellungen Manueller Host und gib Gateway-Host + Port ein (Standard 18789).

Canvas + A2UI

Der iOS-Node rendert einen WKWebView-Canvas. Verwende node.invoke um ihn zu steuern:

openclaw nodes invoke --node "iOS Node" --command canvas.navigate --params '{"url":"http://<gateway-host>:18789/__openclaw__/canvas/"}'

Hinweise:

  • Der Gateway Canvas Host liefert /__openclaw__/canvas/ und /__openclaw__/a2ui/ aus.
  • Er wird vom Gateway HTTP-Server bereitgestellt (gleicher Port wie gateway.port, Standard 18789).
  • Der iOS-Node navigiert beim Verbinden automatisch zu A2UI, wenn eine Canvas-Host-URL beworben wird.
  • Kehre zum eingebauten Scaffold zurück mit canvas.navigate und {"url":""}.

Canvas eval / snapshot

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\"; })()"}'
openclaw nodes invoke --node "iOS Node" --command canvas.snapshot --params '{"maxWidth":900,"format":"jpeg"}'

Voice Wake + Talk-Modus

  • Voice Wake und Talk-Modus sind in den Einstellungen verfügbar.
  • iOS kann Hintergrund-Audio pausieren; behandle Voice-Features als Best-Effort, wenn die App nicht aktiv ist.

Häufige Fehler

  • NODE_BACKGROUND_UNAVAILABLE: Bringe die iOS-App in den Vordergrund (Canvas/Kamera/Bildschirm-Befehle erfordern das).
  • A2UI_HOST_NOT_CONFIGURED: Das Gateway hat keine Canvas-Host-URL beworben; prüfe canvasHost in der Gateway-Konfiguration.
  • Pairing-Prompt erscheint nie: Führe openclaw devices list aus und genehmige manuell.
  • Reconnect schlägt nach Neuinstallation fehl: Das Keychain-Pairing-Token wurde gelöscht; paare den Node neu.

Verwandte Doku