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)
- Starte das Gateway:
openclaw gateway --port 18789
-
Öffne in der iOS-App die Einstellungen und wähle ein entdecktes Gateway (oder aktiviere Manueller Host und gib Host/Port ein).
-
Genehmige die Pairing-Anfrage auf dem Gateway-Host:
openclaw devices list
openclaw devices approve <requestId>
- 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.registeran 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:
- Installiere den offiziellen/TestFlight-iOS-Build.
- Setze
gateway.push.apns.relay.baseUrlauf dem Gateway. - Paare die App mit dem Gateway und lass die Verbindung abschließen.
- Die App veröffentlicht
push.apns.registerautomatisch, nachdem sie ein APNs-Token hat, die Operator-Session verbunden ist und die Relay-Registrierung erfolgreich war. - Danach können
push.test, Reconnect-Wakes und Wake-Nudges die gespeicherte relay-gestützte Registrierung verwenden.
Kompatibilitätshinweis:
OPENCLAW_APNS_RELAY_BASE_URLfunktioniert 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:
-
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.getaufzurufen.
-
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.
-
Gateway-Identitätsdelegation- Vor der Relay-Registrierung ruft die App die Gateway-Identität des gepaarten Gateways über
gateway.identity.getab. - 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.
- Vor der Relay-Registrierung ruft die App die Gateway-Identität des gepaarten Gateways über
-
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.
- Das Gateway speichert das Relay-Handle und Send-Grant von
-
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, Standard18789). - Der iOS-Node navigiert beim Verbinden automatisch zu A2UI, wenn eine Canvas-Host-URL beworben wird.
- Kehre zum eingebauten Scaffold zurück mit
canvas.navigateund{"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üfecanvasHostin der Gateway-Konfiguration.- Pairing-Prompt erscheint nie: Führe
openclaw devices listaus und genehmige manuell. - Reconnect schlägt nach Neuinstallation fehl: Das Keychain-Pairing-Token wurde gelöscht; paare den Node neu.