Passer au contenu

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 montrant des cartes bannière, avec légende, classique, carrousel, vidéo et Apple Wallet

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 to

Utilisez 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 displayType de la payload, ou forcés depuis le code via attributes.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é route custom vers votre propre logique.
  • Prise en charge de l’épinglage : les messages avec actionParams["pinned"] == true flottent 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 PushwooshInboxCell ouverte 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

Types de cartes

Anchor link to

InboxKit 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é).

displayTypeMise en pageChamp de payload requisSe dégrade en
bannerImage pleine page, sans texteimage (inbox_image ou data.image)classic en l’absence d’image
captionedImage en haut, titre + corps en dessousimage (inbox_image ou data.image)classic en l’absence d’image
classicAvatar avec initiale colorée + titre + corps
carouselGalerie multi-images à balayerdata.carousel (tableau de diapositives)classic en l’absence de diapositives
videoAffiche avec badge de lecture, lecteur plein écran au toucherdata.video (url + poster optionnel)classic en l’absence de descripteur
walletBouton « Ajouter à Apple Wallet » (iOS uniquement)data.wallet (URL .pkpass)classic en l’absence d’URL de carte
Carte bannière InboxKit
Carte bannière
Carte avec légende InboxKit
Carte avec légende
Carte classique InboxKit
Carte classique
Carte carrousel InboxKit
Carte carrousel
Carte vidéo InboxKit
Carte vidéo
Carte Apple Wallet InboxKit
Carte Apple Wallet

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 to

Un 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.

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"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 to

Une 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.

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"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 to

La 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.

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"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 to

Les 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 PKAddPassButton standard 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 to

Pour 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 :

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"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 to

Un 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 :

POST https://api.pushwoosh.com/json/1.3/createMessage
{
"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 :

ChampTypeQuand
titlestringRequis. Libellé visible du bouton.
urlstringUne 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.
actionstringJeton 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 choseanyLorsque 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
}
}
}