تطبيق iOS (العقدة)
التوفّر: معاينة داخلية. لم يُوزَّع تطبيق iOS علنًا بعد.ما الذي يفعله
- يتصل ببوابة عبر WebSocket (LAN أو tailnet).
- يوفّر قدرات العقدة: Canvas، ولقطة شاشة، والتقاط الكاميرا، والموقع، ووضع التحدث، والتنبيه الصوتي.
- يستقبل أوامر
node.invokeويبلّغ عن أحداث حالة العقدة.
المتطلبات
- تشغيل البوابة على جهاز آخر (macOS أو Linux أو Windows عبر WSL2).
- مسار الشبكة:
- نفس LAN عبر Bonjour، أو
- Tailnet عبر unicast DNS-SD (مثال على النطاق:
openclaw.internal.)، أو - مضيف/منفذ يدويان (احتياطي).
البدء السريع (اقتران + اتصال)
- ابدأ تشغيل البوابة:
- في تطبيق iOS، افتح Settings واختر بوابة مكتشفة (أو فعّل Manual Host وأدخل المضيف/المنفذ).
- وافق على طلب الاقتران على مضيف البوابة:
requestId جديد.
شغّل openclaw devices list مرة أخرى قبل الموافقة.
- تحقّق من الاتصال:
الإشعارات الفورية المعتمدة على relay للبنيات الرسمية
تستخدم بنيات iOS الرسمية الموزعة relay إشعارات خارجيًا بدلًا من نشر رمز APNs الخام إلى البوابة. متطلب جهة البوابة:- يسجّل تطبيق iOS نفسه لدى relay باستخدام App Attest وإيصال التطبيق.
- يعيد relay مقبض relay معتمًا بالإضافة إلى إذن إرسال ضمن نطاق التسجيل.
- يجلب تطبيق iOS هوية البوابة المقترنة ويضمّنها في تسجيل relay، بحيث يُفوَّض التسجيل المعتمد على relay إلى تلك البوابة المحددة.
- يمرّر التطبيق هذا التسجيل المعتمد على relay إلى البوابة المقترنة عبر
push.apns.register. - تستخدم البوابة مقبض relay المخزن هذا لأوامر
push.testوعمليات الإيقاظ في الخلفية والتنبيهات. - يجب أن يطابق عنوان URL الأساسي لـ relay في البوابة عنوان URL الخاص بـ relay المضمّن في بنية iOS الرسمية/TestFlight.
- إذا اتصل التطبيق لاحقًا ببوابة مختلفة أو ببنية ذات عنوان URL أساسي مختلف لـ relay، فسيحدّث تسجيل relay بدلًا من إعادة استخدام الربط القديم.
- لا حاجة إلى رمز relay على مستوى النشر.
- لا حاجة إلى مفتاح APNs مباشر لعمليات الإرسال الرسمية/TestFlight المعتمدة على relay.
- ثبّت بنية iOS الرسمية/TestFlight.
- عيّن
gateway.push.apns.relay.baseUrlعلى البوابة. - اقترن التطبيق بالبوابة ودعه يُكمل الاتصال.
- ينشر التطبيق
push.apns.registerتلقائيًا بعد أن يحصل على رمز APNs، ويتصل جلسة المشغّل، وينجح تسجيل relay. - بعد ذلك، يمكن لأوامر
push.testوعمليات إيقاظ إعادة الاتصال والتنبيهات استخدام التسجيل المخزن المعتمد على relay.
- ما يزال
OPENCLAW_APNS_RELAY_BASE_URLيعمل كتجاوز مؤقت لمتغير البيئة للبوابة.
تدفق المصادقة والثقة
يوجد relay لفرض قيدين لا يستطيع مسار APNs المباشر إلى البوابة توفيرهما لبنيات iOS الرسمية:- لا يمكن إلا لبنيات OpenClaw iOS الأصلية الموزعة عبر Apple استخدام relay المستضاف.
- لا يمكن للبوابة إرسال إشعارات معتمدة على relay إلا إلى أجهزة iOS التي اقترنت بتلك البوابة تحديدًا.
-
iOS app -> gateway- يقترن التطبيق أولًا بالبوابة عبر تدفق مصادقة البوابة المعتاد.
- يمنح ذلك التطبيق جلسة عقدة موثقة بالإضافة إلى جلسة مشغّل موثقة.
- تُستخدم جلسة المشغّل لاستدعاء
gateway.identity.get.
-
iOS app -> relay- يستدعي التطبيق نقاط نهاية تسجيل relay عبر HTTPS.
- يتضمن التسجيل برهان App Attest بالإضافة إلى إيصال التطبيق.
- يتحقق relay من معرّف الحزمة، وبرهان App Attest، وإيصال Apple، ويتطلب مسار التوزيع الرسمي/الإنتاجي.
- هذا ما يمنع بنيات Xcode/التطوير المحلية من استخدام relay المستضاف. قد تكون البنية المحلية موقّعة، لكنها لا تستوفي برهان التوزيع الرسمي من Apple الذي يتوقعه relay.
-
gateway identity delegation- قبل تسجيل relay، يجلب التطبيق هوية البوابة المقترنة من
gateway.identity.get. - يضمّن التطبيق هوية البوابة هذه في حمولة تسجيل relay.
- يعيد relay مقبض relay وإذن إرسال ضمن نطاق التسجيل يكونان مفوّضين إلى هوية البوابة تلك.
- قبل تسجيل relay، يجلب التطبيق هوية البوابة المقترنة من
-
gateway -> relay- تخزن البوابة مقبض relay وإذن الإرسال القادمين من
push.apns.register. - عند
push.testوعمليات إيقاظ إعادة الاتصال والتنبيهات، توقّع البوابة طلب الإرسال بهوية جهازها الخاصة. - يتحقق relay من كل من إذن الإرسال المخزن وتوقيع البوابة مقابل هوية البوابة المفوّضة من التسجيل.
- لا يمكن لبوابة أخرى إعادة استخدام ذلك التسجيل المخزن، حتى لو حصلت بطريقة ما على المقبض.
- تخزن البوابة مقبض relay وإذن الإرسال القادمين من
-
relay -> APNs- يمتلك relay بيانات اعتماد APNs الإنتاجية ورمز APNs الخام للبنية الرسمية.
- لا تخزّن البوابة رمز APNs الخام للبنيات الرسمية المعتمدة على relay.
- يرسل relay الإشعار النهائي إلى APNs نيابةً عن البوابة المقترنة.
- لإبقاء بيانات اعتماد APNs الإنتاجية خارج بوابات المستخدمين.
- لتجنب تخزين رموز APNs الخام للبنيات الرسمية على البوابة.
- للسماح باستخدام relay المستضاف فقط لبنيات OpenClaw الرسمية/TestFlight.
- لمنع بوابة واحدة من إرسال إشعارات إيقاظ إلى أجهزة iOS مملوكة لبوابة مختلفة.
apps/ios/fastlane/.env فقط
مصادقة App Store Connect / TestFlight مثل ASC_KEY_ID و ASC_ISSUER_ID; ولا يهيئ
تسليم APNs المباشر لبنيات iOS المحلية.
التخزين الموصى به على مضيف البوابة:
.p8 ولا تضعه داخل نسخة المستودع المحلية.
مسارات الاكتشاف
Bonjour (LAN)
يستعرض تطبيق iOS الخدمة_openclaw-gw._tcp على local. وعند التهيئة، يستعرض أيضًا
نطاق اكتشاف wide-area DNS-SD نفسه. تظهر البوابات الموجودة على نفس LAN تلقائيًا من local.;
ويمكن للاكتشاف عبر الشبكات استخدام النطاق واسع النطاق المهيأ من دون تغيير نوع beacon.
Tailnet (عبر الشبكات)
إذا كان mDNS محجوبًا، فاستخدم منطقة unicast DNS-SD (اختر نطاقًا؛ مثال:openclaw.internal.) وTailscale split DNS.
راجع Bonjour للحصول على مثال CoreDNS.
مضيف/منفذ يدويان
في Settings، فعّل Manual Host وأدخل مضيف البوابة + المنفذ (الافتراضي18789).
Canvas + A2UI
تعرض عقدة iOS لوحة canvas عبر WKWebView. استخدمnode.invoke للتحكم بها:
- يقدّم مضيف canvas في البوابة المسارين
/__openclaw__/canvas/و/__openclaw__/a2ui/. - يتم تقديمه من خادم HTTP الخاص بالبوابة (المنفذ نفسه مثل
gateway.port، والافتراضي18789). - تنتقل عقدة iOS تلقائيًا إلى A2UI عند الاتصال عندما يُعلن عن عنوان URL لمضيف canvas.
- للعودة إلى البنية المضمنة، استخدم
canvas.navigateمع{"url":""}.
تقييم canvas / لقطة
التنبيه الصوتي + وضع التحدث
- يتوفر التنبيه الصوتي ووضع التحدث في Settings.
- قد يعلّق iOS الصوت في الخلفية؛ لذا اعتبر ميزات الصوت أفضل جهد عندما لا يكون التطبيق نشطًا.
الأخطاء الشائعة
NODE_BACKGROUND_UNAVAILABLE: اجلب تطبيق iOS إلى الواجهة الأمامية (تتطلب أوامر canvas/الكاميرا/الشاشة ذلك).A2UI_HOST_NOT_CONFIGURED: لم تعلن البوابة عن عنوان URL لمضيف canvas؛ تحقق منcanvasHostفي إعدادات البوابة.- لا يظهر طلب الاقتران مطلقًا: شغّل
openclaw devices listووافق يدويًا. - تفشل إعادة الاتصال بعد إعادة التثبيت: تم مسح رمز الاقتران في Keychain؛ أعد اقتران العقدة.