Configuration de Pushwoosh InboxKit pour iOS
Disponible depuis le SDK iOS 7.0.40.
Pushwoosh InboxKit fournit un écran de boîte de réception UIKit moderne qui s’appuie sur le backend de boîte de réception existant. Six mises en page de cellule par défaut couvrent les formes courantes de cartes de contenu — des simples bannières aux carrousels d’images, en passant par la vidéo intégrée et les cartes Apple Wallet — les boutons CTA intégrés gèrent les interactions les plus courantes, et toute la surface est ouverte au sous-classement si vous avez besoin d’un aspect sur mesure.

Flux InboxKit par défaut avec des cartes bannière, avec légende, classique, carrousel, vidéo et Apple Wallet.
Quand utiliser InboxKit
Anchor link toUtilisez InboxKit pour toute nouvelle intégration iOS. C’est le remplacement recommandé pour l’ancien module Objective-C PushwooshInboxUI.
InboxKit vous offre :
- Six types de cellules intégrés — bannière, avec légende, classique, carrousel, vidéo et Apple Wallet — sélectionnés par message via le
displayTypede la payload, ou forcés depuis le code viaattributes.forceCellKind. Voir Types de cartes pour la liste complète. (La carte Apple Wallet est uniquement pour iOS.) - Des boutons CTA intégrés avec une énumération typée
PushwooshInboxButtonAction(openURL,dismiss,markRead,custom). Le SDK gère les trois premiers automatiquement ; votre délégué routecustomvers votre propre logique. - Prise en charge de l’épinglage : les messages avec
actionParams["pinned"] == trueflottent en haut du flux et affichent un glyphe d’épingle. - Balayage pour supprimer, tirer pour rafraîchir, marquage automatique comme lu à la disparition — tout est activable via
PushwooshInboxKitAttributes. - Stockage persistant : les suppressions et l’état de lecture survivent à un redémarrage du processus même si l’appel réseau n’a pas encore été acquitté.
- Une classe de base
PushwooshInboxCellouverte pour des mises en page entièrement personnalisées.
Le contrat avec le serveur est inchangé — le même backend de boîte de réception Pushwoosh, les mêmes payloads et les mêmes outils de tableau de bord fonctionnent comme avant.
Choisissez votre méthode d’intégration
Anchor link to- Configurer InboxKit avec Swift Package Manager — recommandé pour les nouveaux projets.
- Configurer InboxKit avec CocoaPods — pour les projets utilisant déjà CocoaPods.
Types de cartes
Anchor link toInboxKit choisit une mise en page de cellule par message. Le résolveur par défaut lit displayType depuis la payload du push — placez-le à l’intérieur de l’objet data, que le SDK livre sous actionParams. Lorsque displayType est manquant, le résolveur se rabat sur une heuristique : image + pas de titre → bannière, image + titre → avec légende, sinon classique. Pour forcer une mise en page pour l’ensemble du flux depuis le code, définissez attributes.forceCellKind.
Chaque mise en page riche se dégrade gracieusement : si la payload requise est absente ou malformée, la carte se rabat sur classic plutôt que d’afficher un espace réservé vide (et un WARN est enregistré).
displayType | Mise en page | Champ de payload requis | Se dégrade en |
|---|---|---|---|
banner | Image pleine page, sans texte | image (inbox_image ou data.image) | classic en l’absence d’image |
captioned | Image en haut, titre + corps en dessous | image (inbox_image ou data.image) | classic en l’absence d’image |
classic | Avatar avec initiale colorée + titre + corps | — | — |
carousel | Galerie multi-images à balayer | data.carousel (tableau de diapositives) | classic en l’absence de diapositives |
video | Affiche avec badge de lecture, lecteur plein écran au toucher | data.video (url + poster optionnel) | classic en l’absence de descripteur |
wallet | Bouton « Ajouter à Apple Wallet » (iOS uniquement) | data.wallet (URL .pkpass) | classic en l’absence d’URL de carte |






Les cartes bannière, avec légende et classiques sont pilotées par les champs de message standard (image, titre, corps) plus le tableau optionnel buttons — voir Ajouter des boutons CTA intégrés. Les cartes carrousel, vidéo et Apple Wallet transportent des données structurées supplémentaires à l’intérieur de data, documentées ci-dessous.
Carte carrousel
Anchor link toUn carrousel affiche plusieurs images à partir d’un seul message — une galerie à balayer avec des légendes et des destinations de clic optionnelles par diapositive. Les diapositives se trouvent dans data.carousel. Chaque diapositive nécessite une image ; title (légende en superposition) et url (lien profond ouvert au clic) sont optionnels. Une diapositive sans image est ignorée ; un clic sur une diapositive sans url renvoie à l’action de ligne par défaut du message.
{ "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] }] }}Carte vidéo
Anchor link toUne carte vidéo affiche une image d’affiche avec un badge de lecture ; un clic dessus ouvre un lecteur plein écran (son activé, même si le commutateur silencieux est enclenché). Le descripteur se trouve dans data.video : url est requis et doit être un flux ou un fichier http/https ; poster est une image de prévisualisation optionnelle.
{ "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] }] }}Carte Apple Wallet
Anchor link toLa carte Apple Wallet affiche une image principale optionnelle, un titre et un corps au-dessus du bouton officiel Ajouter à Apple Wallet. Un clic sur le bouton télécharge le .pkpass et présente la feuille système d’ajout de cartes. Utilisez-la pour distribuer des coupons, des cartes de fidélité, des billets ou des cartes d’embarquement directement depuis la boîte de réception. La carte est uniquement pour iOS / Mac Catalyst — sur les autres plateformes, le message s’affiche comme une carte classique.
L’URL de la carte se trouve dans data.wallet, soit sous forme de chaîne de caractères brute, soit sous forme d’objet avec un champ pass. Un data.image optionnel ajoute l’image principale. Le bouton se masque automatiquement s’il n’y a pas d’URL de carte ou si l’appareil ne peut pas ajouter de cartes.
{ "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] }] }}Le résultat est rapporté à votre délégué :
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didAddWalletPassFor message: PWInboxMessageProtocol) { // La carte est maintenant dans le Wallet de l'utilisateur — vous pouvez afficher une confirmation si vous le souhaitez. }
func inboxKit(_ vc: PushwooshInboxKitViewController, didFailToAddWalletPassFor message: PWInboxMessageProtocol, error: Error?) { // Le téléchargement a échoué — proposez une nouvelle tentative, enregistrez dans le journal, etc. }}Les deux rappels sont optionnels (ils ont des implémentations vides par défaut). L’annulation de la feuille système par un utilisateur n’est ni un succès ni un échec, donc aucun rappel n’est déclenché dans ce cas.
Accessibilité
Anchor link toLes cellules InboxKit sont prêtes pour VoiceOver dès le départ. Les cartes bannière, avec légende et classiques exposent leur titre, corps et date via les libellés sous-jacents, et les boutons CTA intégrés lisent leurs propres titres. Les cartes riches ajoutent une sémantique explicite :
- Vidéo — l’affiche est exposée comme un seul élément bouton étiqueté “Lire la vidéo” (traits
.button+.startsMediaSession), donc VoiceOver l’annonce comme un contrôle multimédia plutôt qu’une simple image. - Carrousel — chaque diapositive est un élément bouton dont l’étiquette d’accessibilité est la légende de la diapositive, ou “Diapositive” si elle n’en a pas. L’indicateur de page annonce la position actuelle comme “n sur total”.
- Apple Wallet — le bouton Ajouter à Apple Wallet est le
PKAddPassButtonstandard d’Apple, qui porte sa propre étiquette VoiceOver localisée.
Pour les tests d’interface utilisateur et l’automatisation, deux accessibilityIdentifier stables sont définis : inboxkit.video.play sur l’affiche vidéo et inboxkit.wallet.add sur le bouton Wallet.
Lire des données personnalisées d’un message
Anchor link toPour qu’un push apparaisse dans la boîte de réception, la requête createMessage de l’API Messages doit inclure inbox_image, inbox_date ou inbox_days — sans l’un de ces champs, le push est livré comme une notification normale et n’atteint jamais le flux de la boîte de réception. Les données personnalisées de forme libre vont sous la clé data, que le SDK livre au client en tant que paramètre 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] }] }}Le SDK expose cet objet sur le message de la boîte de réception via actionParams. Lisez-le depuis le délégué lorsque l’utilisateur clique sur la ligne ou un CTA intégré :
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didSelect message: PWInboxMessageProtocol) -> Bool { guard let params = message.actionParams as? [String: Any] else { return true }
// L'objet `data` personnalisé arrive sous la clé "u" — // soit comme un dictionnaire imbriqué, soit comme une chaîne encodée en JSON, // selon la manière dont la payload a été construite en amont. 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 // nous avons géré le clic ; le SDK ne doit pas exécuter l'action par défaut } return true }}La même recherche actionParams["u"] fonctionne à l’intérieur de inboxKit(_:didTapButton:onMessage:) pour les boutons CTA intégrés. Pour les cas de CTA typés (openURL, dismiss, markRead), le SDK exécute déjà l’action par défaut — retournez true pour conserver ce comportement, ou false pour le supprimer et exécuter le vôtre.
Ajouter des boutons CTA intégrés
Anchor link toUn message peut contenir jusqu’à trois boutons d’appel à l’action intégrés. Les boutons se trouvent à côté d’autres données personnalisées à l’intérieur de data sous forme de tableau buttons. Le SDK les affiche automatiquement à l’intérieur des cellules avec légende et classiques :
{ "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] }] }}Chaque objet bouton a ces champs :
| Champ | Type | Quand |
|---|---|---|
title | string | Requis. Libellé visible du bouton. |
url | string | Une URL non vide et analysable produit une action openURL. Le SDK l’ouvre via UIApplication.shared.open à moins que votre délégué ne la supprime. |
action | string | Jeton d’action explicite : dismiss (supprime le message du flux), markRead (marque le message comme lu), ou custom (géré par l’hôte). Insensible à la casse. |
| Autre chose | any | Lorsque action est custom, chaque clé de l’objet bouton, à l’exception de title et action, est transmise à votre délégué en tant que payload personnalisée — convenez d’une clé avec le marketeur (par ex. tag) et effectuez une répartition en fonction de celle-ci. |
Priorité de résolution : d’abord le jeton action explicite, puis url si non vide, sinon le bouton tombe dans custom en transportant la payload complète (moins title et action).
Interceptez les clics depuis votre délégué. La propriété button.action est l’énumération typée PushwooshInboxButtonAction :
extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController, didTapButton button: PushwooshInboxButton, onMessage message: PWInboxMessageProtocol) -> Bool { switch button.action { case .openURL(let url): // Le comportement par défaut est correct — laissons le SDK ouvrir l'URL. return true
case .dismiss, .markRead: // Le SDK gère les deux. Retournez false si vous voulez surcharger. return true
case .custom(let payload): // Bouton personnalisé défini par le marketeur. Effectuez une répartition en fonction d'une clé convenue. if let tag = payload["tag"] as? String { switch tag { case "save_promo": saveCurrentPromoLocally(message: message) default: break } } return true // ignoré pour custom — le SDK n'exécute jamais d'action par défaut ici } }}