Platforms overview
แอป iOS
สถานะพร้อมใช้: พรีวิวภายใน แอป iOS ยังไม่ได้เผยแพร่สู่สาธารณะ
สิ่งที่ทำได้
- เชื่อมต่อกับ Gateway ผ่าน WebSocket (LAN หรือ tailnet)
- เปิดเผยความสามารถของ Node: Canvas, สแนปช็อตหน้าจอ, การจับภาพจากกล้อง, ตำแหน่ง, โหมด Talk, Voice wake
- รับคำสั่ง
node.invokeและรายงานเหตุการณ์สถานะของ Node
ข้อกำหนด
- Gateway ที่ทำงานอยู่บนอุปกรณ์อื่น (macOS, Linux หรือ Windows ผ่าน WSL2)
- เส้นทางเครือข่าย:
- LAN เดียวกันผ่าน Bonjour, หรือ
- Tailnet ผ่าน unicast DNS-SD (โดเมนตัวอย่าง:
openclaw.internal.), หรือ - โฮสต์/พอร์ตแบบกำหนดเอง (สำรอง)
เริ่มต้นอย่างรวดเร็ว (จับคู่ + เชื่อมต่อ)
- เริ่ม Gateway:
openclaw gateway --port 18789
-
ในแอป iOS ให้เปิด Settings แล้วเลือก gateway ที่ค้นพบ (หรือเปิดใช้ Manual Host แล้วป้อนโฮสต์/พอร์ต)
-
อนุมัติคำขอจับคู่บนโฮสต์ Gateway:
openclaw devices list
openclaw devices approve <requestId>
หากแอปพยายามจับคู่อีกครั้งด้วยรายละเอียดการยืนยันตัวตนที่เปลี่ยนไป (บทบาท/ขอบเขต/คีย์สาธารณะ)
คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และจะสร้าง requestId ใหม่
ให้รัน openclaw devices list อีกครั้งก่อนอนุมัติ
ตัวเลือกเสริม: หาก Node iOS เชื่อมต่อจากซับเน็ตที่ควบคุมอย่างเข้มงวดเสมอ คุณ สามารถเลือกใช้การอนุมัติ Node อัตโนมัติครั้งแรกด้วย CIDR หรือ IP ที่ระบุชัดเจน:
{
gateway: {
nodes: {
pairing: {
autoApproveCidrs: ["192.168.1.0/24"],
},
},
},
}
ค่านี้ปิดไว้ตามค่าเริ่มต้น ใช้เฉพาะกับการจับคู่ role: node ใหม่
ที่ไม่มีขอบเขตที่ร้องขอเท่านั้น การจับคู่ Operator/เบราว์เซอร์ และการเปลี่ยนบทบาท ขอบเขต เมทาดาตา หรือ
คีย์สาธารณะใดๆ ยังคงต้องอนุมัติด้วยตนเอง
- ตรวจสอบการเชื่อมต่อ:
openclaw nodes status
openclaw gateway call node.list --params "{}"
Push ที่รองรับด้วย relay สำหรับบิลด์ทางการ
บิลด์ iOS ที่เผยแพร่อย่างเป็นทางการใช้ push relay ภายนอกแทนการเผยแพร่โทเค็น APNs แบบดิบ ไปยัง Gateway
ข้อกำหนดฝั่ง Gateway:
{
gateway: {
push: {
apns: {
relay: {
baseUrl: "https://relay.example.com",
},
},
},
},
}
โฟลว์ทำงานดังนี้:
- แอป iOS ลงทะเบียนกับ relay โดยใช้ App Attest และ StoreKit app transaction JWS
- relay ส่งคืน relay handle แบบทึบ พร้อม send grant ที่ผูกกับขอบเขตการลงทะเบียน
- แอป iOS ดึงตัวตนของ gateway ที่จับคู่ไว้ และรวมไว้ในการลงทะเบียน relay ดังนั้นการลงทะเบียนที่รองรับด้วย relay จึงถูกมอบหมายให้ gateway เฉพาะนั้น
- แอปส่งต่อการลงทะเบียนที่รองรับด้วย relay นั้นไปยัง Gateway ที่จับคู่ไว้ด้วย
push.apns.register - Gateway ใช้ relay handle ที่จัดเก็บไว้นั้นสำหรับ
push.test, การ wake เบื้องหลัง และ wake nudge - URL ฐาน relay ของ Gateway ต้องตรงกับ URL relay ที่ฝังอยู่ในบิลด์ iOS ทางการ/TestFlight
- หากภายหลังแอปเชื่อมต่อกับ Gateway อื่น หรือบิลด์ที่มี URL ฐาน relay ต่างกัน แอปจะรีเฟรชการลงทะเบียน relay แทนการใช้ binding เก่าซ้ำ
สิ่งที่ Gateway ไม่ ต้องใช้สำหรับเส้นทางนี้:
- ไม่ต้องมีโทเค็น relay ระดับ deployment
- ไม่ต้องมีคีย์ APNs โดยตรงสำหรับการส่งแบบ relay-backed ในบิลด์ทางการ/TestFlight
โฟลว์ที่คาดหวังสำหรับ operator:
- ติดตั้งบิลด์ iOS ทางการ/TestFlight
- ตั้งค่า
gateway.push.apns.relay.baseUrlบน Gateway - จับคู่แอปกับ Gateway แล้วปล่อยให้เชื่อมต่อจนเสร็จ
- แอปเผยแพร่
push.apns.registerโดยอัตโนมัติหลังจากมีโทเค็น APNs, เซสชัน operator เชื่อมต่อแล้ว และการลงทะเบียน relay สำเร็จ - หลังจากนั้น
push.test, การ wake เพื่อเชื่อมต่อใหม่ และ wake nudge สามารถใช้การลงทะเบียน relay-backed ที่จัดเก็บไว้ได้
Beacon แสดงว่ายังมีชีวิตในเบื้องหลัง
เมื่อ iOS wake แอปจาก silent push, background refresh หรือเหตุการณ์ significant-location แอป
จะพยายามเชื่อมต่อ Node ใหม่ช่วงสั้นๆ แล้วเรียก node.event ด้วย event: "node.presence.alive"
Gateway บันทึกสิ่งนี้เป็น lastSeenAtMs/lastSeenReason บนเมทาดาตาของ Node/อุปกรณ์ที่จับคู่ไว้เท่านั้น
หลังจากรู้ตัวตนอุปกรณ์ Node ที่ผ่านการยืนยันตัวตนแล้ว
แอปถือว่า background wake ถูกบันทึกสำเร็จก็ต่อเมื่อการตอบกลับของ Gateway มี
handled: true Gateway รุ่นเก่าอาจตอบรับ node.event ด้วย { "ok": true }; การตอบกลับนั้น
เข้ากันได้ แต่ไม่นับเป็นการอัปเดต last-seen ที่คงทน
หมายเหตุความเข้ากันได้:
OPENCLAW_APNS_RELAY_BASE_URLยังใช้งานได้เป็น env override ชั่วคราวสำหรับ Gateway
โฟลว์การยืนยันตัวตนและความเชื่อถือ
relay มีไว้เพื่อบังคับใช้ข้อจำกัดสองข้อที่ APNs โดยตรงบน Gateway ไม่สามารถให้ได้สำหรับ บิลด์ iOS ทางการ:
- เฉพาะบิลด์ iOS ของ OpenClaw ของแท้ที่เผยแพร่ผ่าน Apple เท่านั้นที่ใช้ hosted relay ได้
- Gateway ส่ง push แบบ relay-backed ได้เฉพาะสำหรับอุปกรณ์ iOS ที่จับคู่กับ Gateway เฉพาะนั้น
ทีละ hop:
-
iOS app -> gateway- แอปจับคู่กับ Gateway ผ่านโฟลว์ยืนยันตัวตนปกติของ Gateway ก่อน
- สิ่งนี้ทำให้แอปมีเซสชัน Node ที่ผ่านการยืนยันตัวตน พร้อมเซสชัน operator ที่ผ่านการยืนยันตัวตน
- เซสชัน operator ใช้เรียก
gateway.identity.get
-
iOS app -> relay- แอปเรียก endpoint การลงทะเบียนของ relay ผ่าน HTTPS
- การลงทะเบียนมีหลักฐาน App Attest พร้อม StoreKit app transaction JWS
- relay ตรวจสอบ bundle ID, หลักฐาน App Attest และหลักฐานการเผยแพร่ของ Apple และกำหนดให้ใช้ เส้นทางการเผยแพร่ทางการ/production
- นี่คือสิ่งที่บล็อกบิลด์ Xcode/dev ภายในเครื่องไม่ให้ใช้ hosted relay บิลด์ภายในเครื่องอาจ ถูก signed แล้ว แต่ไม่ตรงตามหลักฐานการเผยแพร่ทางการของ Apple ที่ relay คาดหวัง
-
gateway identity delegation- ก่อนการลงทะเบียน relay แอปดึงตัวตนของ Gateway ที่จับคู่ไว้จาก
gateway.identity.get - แอปรวมตัวตนของ Gateway นั้นไว้ใน payload การลงทะเบียน relay
- relay ส่งคืน relay handle และ send grant ที่ผูกกับขอบเขตการลงทะเบียน ซึ่งถูกมอบหมายให้ ตัวตน Gateway นั้น
- ก่อนการลงทะเบียน relay แอปดึงตัวตนของ Gateway ที่จับคู่ไว้จาก
-
gateway -> relay- Gateway จัดเก็บ relay handle และ send grant จาก
push.apns.register - เมื่อ
push.test, การ wake เพื่อเชื่อมต่อใหม่ และ wake nudge, Gateway ลงนามคำขอส่งด้วย ตัวตนอุปกรณ์ของตัวเอง - relay ตรวจสอบทั้ง send grant ที่จัดเก็บไว้และลายเซ็นของ Gateway เทียบกับตัวตน Gateway ที่ถูกมอบหมายจากการลงทะเบียน
- Gateway อื่นไม่สามารถใช้การลงทะเบียนที่จัดเก็บไว้นั้นซ้ำได้ แม้จะได้ handle มาด้วยวิธีใดก็ตาม
- Gateway จัดเก็บ relay handle และ send grant จาก
-
relay -> APNs- relay เป็นเจ้าของข้อมูลประจำตัว APNs production และโทเค็น APNs แบบดิบสำหรับบิลด์ทางการ
- Gateway ไม่เคยจัดเก็บโทเค็น APNs แบบดิบสำหรับบิลด์ทางการที่รองรับด้วย relay
- relay ส่ง push สุดท้ายไปยัง APNs ในนามของ Gateway ที่จับคู่ไว้
เหตุผลที่สร้างการออกแบบนี้:
- เพื่อเก็บข้อมูลประจำตัว APNs production ไม่ให้อยู่ใน Gateway ของผู้ใช้
- เพื่อหลีกเลี่ยงการจัดเก็บโทเค็น APNs ของบิลด์ทางการแบบดิบบน Gateway
- เพื่ออนุญาตให้ใช้ hosted relay เฉพาะสำหรับบิลด์ OpenClaw ทางการ/TestFlight
- เพื่อป้องกันไม่ให้ Gateway หนึ่งส่ง wake push ไปยังอุปกรณ์ iOS ที่เป็นของ Gateway อื่น
บิลด์ local/manual ยังคงใช้ APNs โดยตรง หากคุณกำลังทดสอบบิลด์เหล่านั้นโดยไม่ใช้ relay Gateway ยังต้องใช้ข้อมูลประจำตัว APNs โดยตรง:
export OPENCLAW_APNS_TEAM_ID="TEAMID"
export OPENCLAW_APNS_KEY_ID="KEYID"
export OPENCLAW_APNS_PRIVATE_KEY_P8="$(cat /path/to/AuthKey_KEYID.p8)"
สิ่งเหล่านี้เป็น env var runtime ของโฮสต์ Gateway ไม่ใช่การตั้งค่า Fastlane apps/ios/fastlane/.env จัดเก็บเฉพาะ
การยืนยันตัวตน App Store Connect / TestFlight เช่น ASC_KEY_ID และ ASC_ISSUER_ID; ไม่ได้กำหนดค่า
การส่ง APNs โดยตรงสำหรับบิลด์ iOS ภายในเครื่อง
พื้นที่จัดเก็บที่แนะนำบนโฮสต์ Gateway:
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"
อย่า commit ไฟล์ .p8 หรือวางไว้ใต้ repo checkout
เส้นทางการค้นพบ
Bonjour (LAN)
แอป iOS browse _openclaw-gw._tcp บน local. และเมื่อกำหนดค่าไว้ จะ browse โดเมน discovery
wide-area DNS-SD เดียวกันด้วย Gateway บน LAN เดียวกันจะปรากฏโดยอัตโนมัติจาก local.;
การค้นพบข้ามเครือข่ายสามารถใช้โดเมน wide-area ที่กำหนดค่าไว้โดยไม่ต้องเปลี่ยนชนิด beacon
Tailnet (ข้ามเครือข่าย)
หาก mDNS ถูกบล็อก ให้ใช้โซน unicast DNS-SD (เลือกโดเมน; ตัวอย่าง:
openclaw.internal.) และ Tailscale split DNS
ดูตัวอย่าง CoreDNS ได้ที่ Bonjour
โฮสต์/พอร์ตแบบกำหนดเอง
ใน Settings ให้เปิดใช้ Manual Host แล้วป้อนโฮสต์ Gateway + พอร์ต (ค่าเริ่มต้น 18789)
Canvas + A2UI
Node iOS render Canvas แบบ WKWebView ใช้ node.invoke เพื่อควบคุม:
openclaw nodes invoke --node "iOS Node" --command canvas.navigate --params '{"url":"http://<gateway-host>:18789/__openclaw__/canvas/"}'
หมายเหตุ:
- โฮสต์ Canvas ของ Gateway ให้บริการ
/__openclaw__/canvas/และ/__openclaw__/a2ui/ - ให้บริการจากเซิร์ฟเวอร์ HTTP ของ Gateway (พอร์ตเดียวกับ
gateway.port, ค่าเริ่มต้น18789) - Node iOS นำทางไปยัง A2UI โดยอัตโนมัติเมื่อเชื่อมต่อ หากมีการประกาศ URL โฮสต์ Canvas
- กลับไปยัง scaffold ในตัวด้วย
canvas.navigateและ{"url":""}
ความสัมพันธ์กับ Computer Use
แอป iOS เป็นพื้นผิว Node บนมือถือ ไม่ใช่ backend ของ Codex Computer Use Codex
Computer Use และ cua-driver mcp ควบคุมเดสก์ท็อป macOS ภายในเครื่องผ่านเครื่องมือ MCP;
แอป iOS เปิดเผยความสามารถของ iPhone ผ่านคำสั่ง Node ของ OpenClaw
เช่น canvas.*, camera.*, screen.*, location.* และ talk.*
Agents ยังคงใช้งานแอป iOS ผ่าน OpenClaw ได้ด้วยการเรียกคำสั่ง Node แต่การเรียกเหล่านั้นผ่านโปรโตคอล Node ของ Gateway และเป็นไปตามขีดจำกัด foreground/background ของ iOS ใช้ Codex Computer Use สำหรับการควบคุมเดสก์ท็อปภายในเครื่อง และใช้หน้านี้สำหรับความสามารถของ Node iOS
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
- Voice wake และโหมด Talk พร้อมใช้งานใน Settings
- Node iOS ที่รองรับ Talk จะประกาศความสามารถ
talkและสามารถประกาศtalk.ptt.start,talk.ptt.stop,talk.ptt.cancelและtalk.ptt.once; Gateway อนุญาตคำสั่ง push-to-talk เหล่านั้นตามค่าเริ่มต้นสำหรับ Node ที่รองรับ Talk และเชื่อถือได้ - iOS อาจระงับเสียงเบื้องหลัง; ให้ถือว่าฟีเจอร์เสียงเป็น best-effort เมื่อแอปไม่ได้ active
ข้อผิดพลาดทั่วไป
NODE_BACKGROUND_UNAVAILABLE: นำแอป iOS มายัง foreground (คำสั่ง canvas/camera/screen ต้องใช้สถานะนี้)A2UI_HOST_NOT_CONFIGURED: Gateway ไม่ได้ประกาศ URL พื้นผิว Plugin Canvas; ตรวจสอบplugins.entries.canvas.config.hostใน การกำหนดค่า Gateway- prompt การจับคู่ไม่ปรากฏ: รัน
openclaw devices listแล้วอนุมัติด้วยตนเอง - การเชื่อมต่อใหม่ล้มเหลวหลังติดตั้งใหม่: โทเค็นการจับคู่ใน Keychain ถูกล้างแล้ว; จับคู่ Node อีกครั้ง