Настройка Pushwoosh InboxKit для iOS
Доступно с iOS SDK 7.0.40.
Pushwoosh InboxKit предоставляет современный экран входящих сообщений на базе UIKit поверх существующего бэкенда для входящих сообщений. Три стандартных макета ячеек охватывают распространенные формы карточек контента в стиле Braze, встроенные CTA-кнопки обрабатывают самые распространенные взаимодействия, и весь интерфейс открыт для создания подклассов, если вам нужен индивидуальный дизайн.

Стандартная лента InboxKit с карточками с баннером, с подписью и классическими.
Когда использовать InboxKit
Anchor link toИспользуйте InboxKit для любой новой интеграции с iOS. Это рекомендуемая замена для устаревшего модуля PushwooshInboxUI на Objective-C.
InboxKit предоставляет вам:
- Три встроенных типа ячеек — с баннером, с подписью, классическая — выбираются для каждого сообщения через
actionParams["displayType"]из вашей полезной нагрузки пуша или принудительно устанавливаются из кода черезattributes.forceCellKind. - Встроенные 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Чтобы пуш появился во входящих, запрос 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": { "promo_id": "SUMMER2026", "screen": "promo_details" }, "ios_root_params": { "displayType": "captioned" }, "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 }
// Пользовательский объект `data` приходит под ключом "u" — // либо как вложенный словарь, либо как строка в формате JSON, // в зависимости от того, как была сформирована полезная нагрузка. 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 // мы обработали нажатие; SDK не должен выполнять действие по умолчанию } return true }}Тот же поиск actionParams["u"] работает внутри inboxKit(_:didTapButton:onMessage:) для встроенных CTA-кнопок. Для типизированных случаев CTA (openURL, dismiss, markRead) SDK уже выполняет действие по умолчанию — верните true, чтобы сохранить это поведение, или false, чтобы подавить его и запустить собственную логику.
Добавление встроенных CTA-кнопок
Anchor link toСообщение может содержать до трех встроенных кнопок призыва к действию (CTA). Кнопки находятся вместе с другими пользовательскими данными внутри 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": { "promo_id": "SUMMER2026", "buttons": [ { "title": "Claim", "url": "https://example.com/promo/SUMMER2026" }, { "title": "Read", "action": "markRead" }, { "title": "Save", "action": "custom", "tag": "save_promo" } ] }, "ios_root_params": { "displayType": "captioned" }, "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): // Поведение по умолчанию подходит — пусть SDK откроет URL. return true
case .dismiss, .markRead: // SDK обрабатывает оба случая. Верните false, если хотите переопределить. return true
case .custom(let payload): // Пользовательская кнопка, определенная маркетологом. Выполняйте диспетчеризацию по согласованному ключу. if let tag = payload["tag"] as? String { switch tag { case "save_promo": saveCurrentPromoLocally(message: message) default: break } } return true // игнорируется для custom — SDK никогда не выполняет здесь действие по умолчанию } }}