إعداد Pushwoosh InboxKit لنظام iOS
متوفر منذ iOS SDK 7.0.40.
يقدم Pushwoosh InboxKit شاشة صندوق وارد حديثة تعتمد على UIKit فوق الواجهة الخلفية الحالية لصندوق الوارد. تغطي ستة تخطيطات خلايا افتراضية أشكال بطاقات المحتوى الشائعة — من اللافتات البسيطة إلى دوارات الصور والفيديو المضمن وبطاقات Apple Wallet — وتتعامل أزرار CTA المضمنة مع التفاعلات الأكثر شيوعًا، والسطح بأكمله مفتوح للتصنيف الفرعي إذا كنت بحاجة إلى مظهر مخصص.

موجز InboxKit الافتراضي مع بطاقات البانر، والتعليقات التوضيحية، والكلاسيكية، والدائرية، والفيديو، وApple Wallet.
متى تستخدم InboxKit
Anchor link toاستخدم InboxKit لأي تكامل جديد لنظام iOS. إنه البديل الموصى به لوحدة Objective-C الأقدم PushwooshInboxUI.
يمنحك InboxKit:
- ستة أنواع خلايا مدمجة — بانر، مع تعليق، كلاسيكي، دائري، فيديو، وApple Wallet — يتم تحديدها لكل رسالة عبر
displayTypeللحمولة، أو فرضها من الكود عبرattributes.forceCellKind. راجع أنواع البطاقات للحصول على القائمة الكاملة. (بطاقة Apple Wallet مخصصة لنظام iOS فقط.) - أزرار CTA مضمنة مع تعداد
PushwooshInboxButtonActionمحدد النوع (openURL،dismiss،markRead،custom). يتعامل SDK مع الثلاثة الأولى تلقائيًا؛ ويوجه مندوبكcustomإلى منطقك الخاص. - دعم التثبيت: الرسائل التي تحتوي على
actionParams["pinned"] == trueتطفو إلى أعلى الموجز وتعرض رمز دبوس. - السحب للحذف، السحب للتحديث، التحديد التلقائي كمقروء عند الاختفاء — كلها قابلة للتبديل عبر
PushwooshInboxKitAttributes. - تخزين دائم: تبقى عمليات الحذف وحالة القراءة بعد إعادة تشغيل العملية حتى لو لم يتم الإقرار باستدعاء الشبكة بعد.
- فئة أساسية مفتوحة
PushwooshInboxCellللتخطيطات المخصصة بالكامل.
عقد الخادم لم يتغير — تعمل نفس الواجهة الخلفية لصندوق الوارد في Pushwoosh، والحمولات، وأدوات لوحة التحكم كما كان من قبل.
اختر طريقة التكامل الخاصة بك
Anchor link to- إعداد InboxKit باستخدام Swift Package Manager — موصى به للمشاريع الجديدة.
- إعداد InboxKit باستخدام CocoaPods — للمشاريع التي تستخدم CocoaPods بالفعل.
أنواع البطاقات
Anchor link toيختار InboxKit تخطيط خلية لكل رسالة. يقرأ المحلل الافتراضي displayType من حمولة الدفع — ضعه داخل كائن data، الذي يقدمه SDK تحت actionParams. عندما يكون displayType مفقودًا، يعود المحلل إلى طريقة استدلالية: صورة + لا يوجد عنوان ← بانر، صورة + عنوان + نص ← مع تعليق، وإلا كلاسيكي. لفرض تخطيط واحد للموجز بأكمله من الكود، قم بتعيين attributes.forceCellKind.
كل تخطيط غني يتدهور برشاقة: إذا كان حقل إلزامي غائبًا أو مشوهًا، تعود البطاقة إلى classic بدلاً من عرض عنصر نائب فارغ (ويتم تسجيل WARN مع السبب). classic هو الحل البديل النهائي ويعرض كل ما تحمله الرسالة؛ ومن المتوقع أن يملأ محرر الرسائل عنوانها ونصها وأيقونتها.
displayType | التخطيط | حقل الحمولة المطلوب | يتدهور إلى |
|---|---|---|---|
banner | صورة بعرض كامل، بدون نص | صورة (inbox_image أو data.image) | classic عند عدم وجود صورة |
captioned | صورة في الأعلى، عنوان + نص أدناه | صورة (inbox_image أو data.image)، title و content للرسالة | classic عند فقدان الصورة أو العنوان أو النص |
classic | صورة رمزية أولية ملونة + عنوان + نص | — (من المتوقع وجود عنوان ونص وأيقونة) | — |
carousel | معرض صور متعددة قابل للسحب | title و content للرسالة، data.carousel (1–5 شرائح) | classic عند عدم وجود شرائح أو عدم وجود عنوان/نص |
video | ملصق مع شارة تشغيل، مشغل بملء الشاشة عند النقر | data.video (url + poster اختياري) | classic عند عدم وجود واصف |
wallet | زر “Add to Apple Wallet” (لنظام iOS فقط) | data.wallet (عنوان URL لـ .pkpass) | classic عند عدم وجود عنوان URL للمرور |






يتم تشغيل بطاقات البانر، والتعليقات التوضيحية، والكلاسيكية بواسطة حقول الرسائل القياسية (الصورة، العنوان، النص) بالإضافة إلى مصفوفة buttons الاختيارية — راجع إضافة أزرار CTA مضمنة. تحمل بطاقات الدوارة والفيديو وApple Wallet بيانات منظمة إضافية داخل data، موثقة أدناه.
بطاقة دائرية
Anchor link toتعرض البطاقة الدائرية عدة صور من رسالة واحدة — معرض قابل للسحب مع تعليقات اختيارية لكل شريحة ووجهات للنقر. توجد الشرائح في data.carousel. تحتاج كل شريحة إلى image؛ title (تراكب التعليق) و url (رابط عميق يفتح عند النقر) اختيارية. يتم إسقاط الشريحة التي لا تحتوي على صورة؛ والنقر على شريحة بدون url ينتقل إلى إجراء الصف الافتراضي للرسالة. يتم عرض 5 شرائح على الأكثر — يتم إسقاط الشرائح الإضافية (الشريحة التي لا تحتوي على صورة لا تستهلك مكانًا). title و content للرسالة إلزاميان لهذا التخطيط؛ بدونهما تتدهور البطاقة إلى classic.
{ "request": { "application": "XXXXX-XXXXX", "auth": "API_TOKEN", "notifications": [{ "send_date": "now", "ios_title": "New arrivals", "content": "Swipe through this week's drops", "inbox_days": 7, "data": { "displayType": "carousel", "carousel": [ { "image": "https://cdn.example.com/inbox/1.jpg", "title": "New in", "url": "myapp://product/1" }, { "image": "https://cdn.example.com/inbox/2.jpg", "title": "On sale", "url": "myapp://product/2" }, { "image": "https://cdn.example.com/inbox/3.jpg" } ] }, "platforms": [1] }] }}بطاقة فيديو
Anchor link toتعرض بطاقة الفيديو صورة ملصق مع شارة تشغيل؛ يؤدي النقر عليها إلى فتح مشغل بملء الشاشة (الصوت قيد التشغيل، حتى مع تعشيق مفتاح الصامت). يوجد الواصف في data.video: url مطلوب ويجب أن يكون بثًا أو ملفًا http/https؛ poster هو صورة معاينة اختيارية.
{ "request": { "application": "XXXXX-XXXXX", "auth": "API_TOKEN", "notifications": [{ "send_date": "now", "ios_title": "Watch the reveal", "content": "Tap to play", "inbox_days": 7, "data": { "displayType": "video", "video": { "url": "https://cdn.example.com/inbox/clip.mp4", "poster": "https://cdn.example.com/inbox/poster.jpg" } }, "platforms": [1] }] }}بطاقة Apple Wallet
Anchor link toتعرض بطاقة Apple Wallet صورة بطل اختيارية وعنوانًا ونصًا فوق زر Add to Apple Wallet الرسمي. يؤدي النقر على الزر إلى تنزيل .pkpass وتقديم ورقة إضافة التصاريح الخاصة بالنظام. استخدمها لتقديم القسائم أو بطاقات الولاء أو التذاكر أو بطاقات الصعود إلى الطائرة مباشرة من صندوق الوارد. البطاقة مخصصة لنظام iOS / Mac Catalyst فقط — على المنصات الأخرى، يتم عرض الرسالة كبطاقة كلاسيكية.
يوجد عنوان URL للمرور في data.wallet، إما كسلسلة نصية مجردة أو ككائن يحتوي على حقل pass. تضيف data.image الاختيارية صورة البطل. يخفي الزر نفسه تلقائيًا عند عدم وجود عنوان URL للمرور أو عندما لا يتمكن الجهاز من إضافة التصاريح.
{ "request": { "application": "XXXXX-XXXXX", "auth": "API_TOKEN", "notifications": [{ "send_date": "now", "ios_title": "Your loyalty card is ready", "content": "Add it to Apple Wallet in one tap", "inbox_days": 7, "data": { "displayType": "wallet", "image": "https://cdn.example.com/inbox/loyalty.png", "wallet": "https://passes.example.com/v1/passes/pass.com.example.loyalty/abc123?token=…" }, "platforms": [1] }] }}يتم إبلاغ مندوبك بالنتيجة:
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didAddWalletPassFor message: PWInboxMessageProtocol) { // The pass is now in the user's Wallet — show a confirmation if you like. }
func inboxKit(_ vc: PushwooshInboxKitViewController, didFailToAddWalletPassFor message: PWInboxMessageProtocol, error: Error?) { // Download failed — surface a retry, log, etc. }}كلا ردود الاتصال اختيارية (تحمل تطبيقات فارغة افتراضية). إلغاء المستخدم لورقة النظام ليس نجاحًا ولا فشلاً، لذلك لا يتم إطلاق أي رد اتصال في هذه الحالة.
إمكانية الوصول
Anchor link toخلايا InboxKit جاهزة لـ VoiceOver خارج الصندوق. تعرض بطاقات البانر، والتعليقات التوضيحية، والكلاسيكية عنوانها ونصها وتاريخها من خلال التسميات الأساسية، وتقرأ أزرار CTA المضمنة عناوينها الخاصة. تضيف البطاقات الغنية دلالات صريحة:
- الفيديو — يتم عرض الملصق كعنصر زر واحد يسمى “تشغيل الفيديو” (السمات
.button+.startsMediaSession)، لذلك يعلن VoiceOver عنه كعنصر تحكم في الوسائط بدلاً من صورة عادية. - الدوارة — كل شريحة هي عنصر زر تكون تسمية إمكانية الوصول الخاصة به هي تعليق الشريحة، أو “شريحة” عندما لا تحتوي على أي تعليق. يعلن مؤشر الصفحة عن الموضع الحالي كـ “n من الإجمالي”.
- Apple Wallet — زر Add to Apple Wallet هو زر
PKAddPassButtonالقياسي من Apple، والذي يحمل تسمية VoiceOver المترجمة الخاصة به.
لإجراء اختبارات واجهة المستخدم والأتمتة، يتم تعيين معرفين ثابتين لـ accessibilityIdentifier: inboxkit.video.play على ملصق الفيديو و inboxkit.wallet.add على زر Wallet.
قراءة البيانات المخصصة من رسالة
Anchor link toلجعل إشعار الدفع يظهر في صندوق الوارد، يجب أن يتضمن طلب createMessage في Messages API inbox_image أو inbox_date أو inbox_days — بدون أحد هذه الحقول، يتم تسليم إشعار الدفع كإشعار عادي ولا يصل أبدًا إلى موجز صندوق الوارد. توضع البيانات المخصصة ذات الشكل الحر تحت مفتاح data، الذي يقدمه SDK إلى العميل كمعلمة u:
{ "request": { "application": "XXXXX-XXXXX", "auth": "API_TOKEN", "notifications": [{ "send_date": "now", "ios_title": "Summer sale", "content": "30% off everything — limited time only", "inbox_image": "https://cdn.example.com/inbox/summer.png", "inbox_days": 7, "data": { "displayType": "captioned", "promo_id": "SUMMER2026", "screen": "promo_details" }, "platforms": [1] }] }}يعرض SDK هذا الكائن في رسالة صندوق الوارد من خلال actionParams. اقرأه من المندوب عندما ينقر المستخدم على الصف أو على زر CTA مضمن:
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didSelect message: PWInboxMessageProtocol) -> Bool { guard let params = message.actionParams as? [String: Any] else { return true }
// The custom `data` object arrives under the "u" key — // either as a nested dictionary or as a JSON-encoded string, // depending on how the payload was built upstream. let custom: [String: Any]? = { if let dict = params["u"] as? [String: Any] { return dict } if let raw = params["u"] as? String, let bytes = raw.data(using: .utf8), let parsed = try? JSONSerialization.jsonObject(with: bytes) as? [String: Any] { return parsed } return nil }()
if let promoId = custom?["promo_id"] as? String { navigateToPromo(promoId) return false // we handled the tap; SDK should not run the default action } return true }}يعمل نفس البحث actionParams["u"] داخل inboxKit(_:didTapButton:onMessage:) لأزرار CTA المضمنة. بالنسبة لحالات CTA المكتوبة (openURL، dismiss، markRead)، يقوم SDK بالفعل بتنفيذ الإجراء الافتراضي — أرجع true للحفاظ على هذا السلوك، أو false لقمعه وتشغيل سلوكك الخاص.
إضافة أزرار CTA مضمنة
Anchor link toيمكن أن تحمل الرسالة ما يصل إلى ثلاثة أزرار استدعاء مضمنة. توجد الأزرار جنبًا إلى جنب مع البيانات المخصصة الأخرى داخل data كمصفوفة buttons. يقوم SDK بعرضها تلقائيًا داخل الخلايا ذات التعليقات التوضيحية والكلاسيكية:
{ "request": { "application": "XXXXX-XXXXX", "auth": "API_TOKEN", "notifications": [{ "send_date": "now", "ios_title": "New promo card", "content": "Tap a button to claim or save", "inbox_image": "https://cdn.example.com/inbox/promo.png", "inbox_days": 7, "data": { "displayType": "captioned", "promo_id": "SUMMER2026", "buttons": [ { "title": "Claim", "url": "https://example.com/promo/SUMMER2026" }, { "title": "Read", "action": "markRead" }, { "title": "Save", "action": "custom", "tag": "save_promo" } ] }, "platforms": [1] }] }}يحتوي كل كائن زر على هذه الحقول:
| الحقل | النوع | متى |
|---|---|---|
title | string | مطلوب. تسمية الزر المرئية. |
url | string | ينتج عنوان URL غير فارغ وقابل للتحليل إجراء openURL. يفتحه SDK عبر UIApplication.shared.open ما لم يقم مندوبك بقمعه. |
action | string | رمز إجراء صريح: dismiss (يزيل الرسالة من الموجز)، markRead (يحدد الرسالة كمقروءة)، أو custom (يتعامل معه المضيف). غير حساس لحالة الأحرف. |
| أي شيء آخر | any | عندما يكون action هو custom، يتم إعادة توجيه كل مفتاح في كائن الزر باستثناء title و action إلى مندوبك كحمولة مخصصة — اتفق على مفتاح مع المسوق (مثل tag) وقم بالتوزيع بناءً عليه. |
أولوية الحل: رمز action الصريح أولاً، ثم url إذا كان غير فارغ، وإلا فإن الزر يقع في custom حاملاً الحمولة الكاملة (ناقص title و action).
اعترض النقرات من مندوبك. خاصية button.action هي تعداد PushwooshInboxButtonAction المكتوب:
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didTapButton button: PushwooshInboxButton, onMessage message: PWInboxMessageProtocol) -> Bool { switch button.action { case .openURL(let url): // Default behavior is fine — let SDK open the URL. return true
case .dismiss, .markRead: // SDK handles both. Return false if you want to override. return true
case .custom(let payload): // Marketer-defined custom button. Dispatch on a key you agreed on. if let tag = payload["tag"] as? String { switch tag { case "save_promo": saveCurrentPromoLocally(message: message) default: break } } return true // ignored for custom — SDK never runs a default action here } }}