Pular para o conteúdo

Configurando o Pushwoosh InboxKit para iOS

Disponível desde o SDK do iOS 7.0.40.

O Pushwoosh InboxKit oferece uma tela de caixa de entrada moderna em UIKit sobre o backend de caixa de entrada existente. Seis layouts de célula padrão cobrem os formatos comuns de cartões de conteúdo — de banners simples a carrosséis de imagens, vídeo em linha e passes da Apple Wallet — botões de CTA em linha lidam com as interações mais comuns, e toda a superfície está aberta para subclassificação se você precisar de um visual personalizado.

Feed do InboxKit mostrando cartões de banner, com legenda, clássico, carrossel, vídeo e Apple Wallet

Feed padrão do InboxKit com cartões de banner, com legenda, clássico, carrossel, vídeo e Apple Wallet.

Quando usar o InboxKit

Anchor link to

Use o InboxKit para qualquer nova integração com iOS. É o substituto recomendado para o módulo mais antigo em Objective-C PushwooshInboxUI.

O InboxKit oferece a você:

  • Seis tipos de célula integrados — banner, com legenda, clássico, carrossel, vídeo e Apple Wallet — selecionados por mensagem através do displayType do payload, ou forçados a partir do código via attributes.forceCellKind. Veja Tipos de cartão para a lista completa. (O cartão Apple Wallet é exclusivo para iOS.)
  • Botões de CTA em linha com um enum tipado PushwooshInboxButtonAction (openURL, dismiss, markRead, custom). O SDK lida com os três primeiros automaticamente; seu delegate roteia custom para sua própria lógica.
  • Suporte à fixação: mensagens com actionParams["pinned"] == true flutuam para o topo do feed e renderizam um ícone de pino.
  • Deslizar para excluir, puxar para atualizar, marcação automática como lida ao desaparecer — tudo pode ser ativado/desativado via PushwooshInboxKitAttributes.
  • Armazenamento persistente: exclusões e estado de leitura sobrevivem a uma reinicialização do processo, mesmo que a chamada de rede ainda não tenha sido confirmada.
  • Uma classe base PushwooshInboxCell aberta para layouts totalmente personalizados.

O contrato do servidor permanece inalterado — o mesmo backend de caixa de entrada do Pushwoosh, payloads e ferramentas do painel funcionam como antes.

Escolha seu método de integração

Anchor link to

Tipos de cartão

Anchor link to

O InboxKit escolhe um layout de célula por mensagem. O resolvedor padrão lê displayType do payload do push — coloque-o dentro do objeto data, que o SDK entrega sob actionParams. Quando displayType está ausente, o resolvedor recorre a uma heurística: imagem + sem título → banner, imagem + título + corpo → com legenda, caso contrário, clássico. Para forçar um layout para todo o feed a partir do código, defina attributes.forceCellKind.

Cada layout rico degrada-se graciosamente: se um campo obrigatório estiver ausente ou malformado, o cartão volta para classic em vez de renderizar um espaço vazio (e um WARN é registrado com o motivo). classic é o fallback terminal e renderiza o que a mensagem contiver; espera-se que o editor de mensagens preencha seu título, corpo e ícone.

displayTypeLayoutCampo de payload obrigatórioDegrada para
bannerImagem de sangria total, sem textoimagem (inbox_image ou data.image)classic quando não há imagem
captionedImagem no topo, título + corpo abaixoimagem (inbox_image ou data.image), title e content da mensagemclassic quando a imagem, título ou corpo estão ausentes
classicAvatar inicial colorido + título + corpo— (título, corpo e ícone esperados)—
carouselGaleria de múltiplas imagens deslizáveltitle e content da mensagem, data.carousel (1–5 slides)classic quando não há slides ou título/corpo
videoPôster com ícone de play, player em tela cheia ao tocardata.video (url + poster opcional)classic quando não há descritor
walletBotão “Adicionar à Carteira da Apple” (apenas iOS)data.wallet (URL do .pkpass)classic quando não há URL do passe
Cartão de banner do InboxKit
Cartão de banner
Cartão com legenda do InboxKit
Cartão com legenda
Cartão clássico do InboxKit
Cartão clássico
Cartão de carrossel do InboxKit
Cartão de carrossel
Cartão de vídeo do InboxKit
Cartão de vídeo
Cartão Apple Wallet do InboxKit
Cartão Apple Wallet

Os cartões de banner, com legenda e clássicos são controlados pelos campos de mensagem padrão (imagem, título, corpo) mais o array opcional buttons — veja Adicionar botões de CTA em linha. Os cartões de carrossel, vídeo e Apple Wallet carregam dados estruturados extras dentro de data, documentados abaixo.

Cartão de carrossel

Anchor link to

Um carrossel renderiza várias imagens de uma única mensagem — uma galeria deslizável com legendas opcionais por slide e destinos de toque. Os slides ficam em data.carousel. Cada slide precisa de uma image; title (legenda sobreposta) e url (deep link aberto ao tocar) são opcionais. Um slide sem imagem é descartado; um toque em um slide sem url recorre à ação padrão da linha da mensagem. No máximo 5 slides são mostrados — slides extras são descartados (um slide sem imagem não ocupa um lugar). O title e o content da mensagem são obrigatórios para este layout; sem eles, o cartão degrada para classic.

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]
}]
}
}

Cartão de vídeo

Anchor link to

Um cartão de vídeo mostra uma imagem de pôster com um ícone de play; tocá-lo abre um player em tela cheia (som ligado, mesmo com o interruptor de silêncio ativado). O descritor fica em data.video: url é obrigatório e deve ser um stream ou arquivo http/https; poster é uma imagem de pré-visualização opcional.

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]
}]
}
}

Cartão Apple Wallet

Anchor link to

O cartão Apple Wallet mostra uma imagem de destaque opcional, título e corpo acima do botão oficial Adicionar à Carteira da Apple. Tocar no botão baixa o .pkpass e apresenta a tela do sistema para adicionar passes. Use-o para entregar cupons, cartões de fidelidade, ingressos ou cartões de embarque diretamente da caixa de entrada. O cartão é exclusivo para iOS / Mac Catalyst — em outras plataformas, a mensagem é renderizada como um cartão clássico.

A URL do passe fica em data.wallet, seja como uma string simples ou como um objeto com um campo pass. Uma data.image opcional adiciona a imagem de destaque. O botão se esconde automaticamente quando não há URL de passe ou o dispositivo não pode adicionar passes.

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]
}]
}
}

O resultado é reportado ao seu delegate:

extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController,
didAddWalletPassFor message: PWInboxMessageProtocol) {
// O passe está agora na Carteira do usuário — mostre uma confirmação se desejar.
}
func inboxKit(_ vc: PushwooshInboxKitViewController,
didFailToAddWalletPassFor message: PWInboxMessageProtocol,
error: Error?) {
// O download falhou — apresente uma opção de tentar novamente, registre o erro, etc.
}
}

Ambos os callbacks são opcionais (eles carregam implementações vazias padrão). Um usuário cancelando a tela do sistema não é nem sucesso nem falha, então nenhum callback é acionado nesse caso.

Acessibilidade

Anchor link to

As células do InboxKit estão prontas para o VoiceOver desde o início. Os cartões de banner, com legenda e clássicos expõem seu título, corpo e data através dos rótulos subjacentes, e os botões de CTA em linha leem seus próprios títulos. Os cartões ricos adicionam semântica explícita:

  • Vídeo — o pôster é exposto como um único elemento de botão rotulado “Reproduzir vídeo” (atributos .button + .startsMediaSession), para que o VoiceOver o anuncie como um controle de mídia em vez de uma imagem simples.
  • Carrossel — cada slide é um elemento de botão cujo rótulo de acessibilidade é a legenda do slide, ou “Slide” quando não tem nenhuma. O indicador de página anuncia a posição atual como “n de total”.
  • Apple Wallet — o botão Adicionar à Carteira da Apple é o PKAddPassButton padrão da Apple, que carrega seu próprio rótulo de VoiceOver localizado.

Para testes de UI e automação, dois accessibilityIdentifiers estáveis são definidos: inboxkit.video.play no pôster do vídeo e inboxkit.wallet.add no botão da Carteira.

Ler dados personalizados de uma mensagem

Anchor link to

Para que um push apareça na caixa de entrada, a solicitação createMessage da API de Mensagens deve incluir inbox_image, inbox_date ou inbox_days — sem um desses campos, o push é entregue como uma notificação regular e nunca chega ao feed da caixa de entrada. Dados personalizados de formato livre vão sob a chave data, que o SDK entrega ao cliente como o parâmetro 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]
}]
}
}

O SDK expõe esse objeto na mensagem da caixa de entrada através de actionParams. Leia-o do delegate quando o usuário tocar na linha ou em um CTA em linha:

extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController,
didSelect message: PWInboxMessageProtocol) -> Bool {
guard let params = message.actionParams as? [String: Any] else { return true }
// O objeto `data` personalizado chega sob a chave "u" —
// seja como um dicionário aninhado ou como uma string codificada em JSON,
// dependendo de como o payload foi construído.
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 // nós lidamos com o toque; o SDK não deve executar a ação padrão
}
return true
}
}

A mesma busca actionParams["u"] funciona dentro de inboxKit(_:didTapButton:onMessage:) para botões de CTA em linha. Para os casos de CTA tipados (openURL, dismiss, markRead), o SDK já executa a ação padrão — retorne true para manter esse comportamento, ou false para suprimi-lo e executar o seu próprio.

Adicionar botões de CTA em linha

Anchor link to

Uma mensagem pode carregar até três botões de chamada para ação (CTA) em linha. Os botões ficam junto com outros dados personalizados dentro de data como um array buttons. O SDK os renderiza automaticamente dentro das células com legenda e clássicas:

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]
}]
}
}

Cada objeto de botão tem estes campos:

CampoTipoQuando
titlestringObrigatório. Rótulo visível do botão.
urlstringUma URL não vazia e analisável produz uma ação openURL. O SDK a abre via UIApplication.shared.open, a menos que seu delegate a suprima.
actionstringToken de ação explícito: dismiss (remove a mensagem do feed), markRead (marca a mensagem como lida) ou custom (tratado pelo host). Insensível a maiúsculas e minúsculas.
Qualquer outra coisaanyQuando action é custom, cada chave no objeto do botão, exceto title e action, é encaminhada para o seu delegate como o payload personalizado — combine uma chave com o profissional de marketing (por exemplo, tag) e despache com base nela.

Prioridade de resolução: primeiro o token action explícito, depois url se não estiver vazio, caso contrário, o botão cai em custom carregando o payload completo (menos title e action).

Intercepte os toques do seu delegate. A propriedade button.action é o enum tipado PushwooshInboxButtonAction:

extension MyInboxHost: PushwooshInboxKitDelegate {
func inboxKit(_ vc: PushwooshInboxKitViewController,
didTapButton button: PushwooshInboxButton,
onMessage message: PWInboxMessageProtocol) -> Bool {
switch button.action {
case .openURL(let url):
// O comportamento padrão está bom — deixe o SDK abrir a URL.
return true
case .dismiss, .markRead:
// O SDK lida com ambos. Retorne false se quiser substituir.
return true
case .custom(let payload):
// Botão personalizado definido pelo profissional de marketing. Despache com base em uma chave que vocês combinaram.
if let tag = payload["tag"] as? String {
switch tag {
case "save_promo":
saveCurrentPromoLocally(message: message)
default:
break
}
}
return true // ignorado para personalizado — o SDK nunca executa uma ação padrão aqui
}
}
}