Saltar al contenido

Historias push para iOS

Las historias push convierten una notificación push expandida en una experiencia de historias a pantalla completa, al estilo de Instagram: imágenes a sangre completa, barras de progreso superiores, avance automático de páginas, toque para navegar y un botón con un enlace profundo (deep link). Se renderizan mediante una Extensión de Contenido de Notificación (Notification Content Extension) que utiliza el módulo independiente PushwooshNotificationUI: solo tienes que crear una subclase de un controlador de vista y el SDK se encarga del análisis, la carga de imágenes, el progreso, la temporización, la navegación y los enlaces profundos.

Disponible desde la versión 7.0.46.

Historias push reproduciéndose en una notificación expandida

1. Añade una Extensión de Contenido de Notificación

Anchor link to

En Xcode, elige Archivo > Nuevo > Destino… (File > New > Target…), selecciona Extensión de Contenido de Notificación (Notification Content Extension) y asígnale un nombre (por ejemplo, StoriesContentExtension).

Añadiendo un destino de Extensión de Contenido de Notificación en Xcode

2. Añade el módulo PushwooshNotificationUI

Anchor link to

PushwooshNotificationUI es un módulo independiente sin otras dependencias de Pushwoosh, por lo que se mantiene pequeño dentro del proceso de la extensión. Añádelo al destino de la extensión de contenido (no al destino de la aplicación).

Swift Package Manager

Añadiendo el paquete PushwooshNotificationUI al destino de la extensión

CocoaPods

target 'StoriesContentExtension' do
use_frameworks!
pod 'PushwooshXCFramework/PushwooshNotificationUI'
end

3. Crea una subclase del controlador de vista de historias

Anchor link to

Reemplaza el cuerpo del NotificationViewController generado con una subclase de PushwooshStoriesViewController. Esa es toda la integración.

import PushwooshNotificationUI
class NotificationViewController: PushwooshStoriesViewController {}

4. Configura el Info.plist de la extensión

Anchor link to

En el Info.plist de la extensión de contenido, establece las siguientes claves en NSExtension > NSExtensionAttributes:

<key>UNNotificationExtensionCategory</key>
<string>PW_STORIES</string>
<key>UNNotificationExtensionUserInteractionEnabled</key>
<true/>
<key>UNNotificationExtensionDefaultContentHidden</key>
<true/>
<key>UNNotificationExtensionInitialContentSizeRatio</key>
<real>1.5</real>

5. Envía una notificación de historias push

Anchor link to

Envía una notificación cuya categoría sea PW_STORIES y cuyos datos personalizados contengan un bloque pw_stories. Utiliza el campo dedicado ios_category_custom para la categoría y el campo data para el payload de las historias.

{
"request": {
"application": "APPLICATION_CODE",
"auth": "API_ACCESS_TOKEN",
"notifications": [
{
"send_date": "now",
"content": "Tap to explore",
"ios_title": "Push Stories",
"ios_category_custom": "PW_STORIES",
"ios_root_params": {
"aps": {
"mutable-content": 1
}
},
"data": {
"pw_stories": {
"pages": [
{
"image": "https://example.com/story-1.jpg",
"duration": 5.0,
"link": "yourapp://page1",
"button_title": "Get started",
"title": "Welcome",
"subtitle": "Swipe to explore what's new"
},
{
"image": "https://example.com/story-2.jpg",
"duration": 4.0,
"link": "yourapp://page2",
"button_title": "Learn more",
"title": "Stay in the loop",
"subtitle": "Updates, tips and more"
}
]
}
}
}
]
}
}

Cada página admite los siguientes campos. Solo image es obligatorio; el resto son opcionales.

CampoDescripción
imageURL de la imagen a pantalla completa para la página.
durationSegundos que la página permanece en pantalla antes de avanzar automáticamente. El valor predeterminado es de unos 5 segundos.
linkEnlace profundo (deep link) que se abre al tocar el botón de la página.
button_titleTítulo del botón de la página.
titleTexto del título superpuesto en la página.
subtitleTexto del subtítulo superpuesto en la página.

Personalización

Anchor link to

Sobrescribe las propiedades en tu subclase para ajustar la experiencia. Todas tienen valores predeterminados razonables.

import PushwooshNotificationUI
class NotificationViewController: PushwooshStoriesViewController {
override var storyAspectRatio: CGFloat { 1.5 } // keep in sync with InitialContentSizeRatio
override var hapticsEnabled: Bool { true }
override var longPressToPauseEnabled: Bool { true }
override var crossfadesBetweenPages: Bool { true }
override var loopsAfterLastPage: Bool { false }
}
PropiedadPredeterminadoDescripción
storyAspectRatio1.5Relación de aspecto (alto ÷ ancho) del área de las historias. Mantenla sincronizada con UNNotificationExtensionInitialContentSizeRatio.
hapticsEnabledfalseReproduce una ligera respuesta táctil al navegar por las zonas de toque.
longPressToPauseEnabledfalseMantener presionado pausa la página actual; soltar reanuda.
crossfadesBetweenPagesfalseTransición suave (cross-dissolve) entre páginas en lugar de un corte brusco. Vuelve a un cambio instantáneo si la opción Reducir Movimiento está activada.
loopsAfterLastPagefalseReinicia desde la primera página después de que la última termine.
appGroupIdentifiernilApp Group compartido con una Extensión de Servicio de Notificación (Notification Service Extension) para la precarga de medios (ver más abajo).

También puedes sobrescribir showDefaultContent(for:) para personalizar el contenido de respaldo que se muestra cuando el payload falta o está malformado (por defecto, muestra el cuerpo de la alerta).

Precarga de medios

Anchor link to

Para obtener un primer fotograma instantáneo y sin conexión, comparte un App Group entre tu Extensión de Contenido y una Extensión de Servicio de Notificación. Sobrescribe appGroupIdentifier en el controlador de historias y luego precarga los medios desde el didReceive(_:withContentHandler:) de tu Extensión de Servicio:

import PushwooshNotificationUI
PushwooshStoriesMediaPrefetcher.prefetch(
userInfo: request.content.userInfo,
appGroupIdentifier: "group.com.example.app"
) {
contentHandler(bestAttemptContent)
}

Habilita la capacidad App Groups en ambas extensiones con el mismo identificador de grupo y envía mutable-content: 1 para que se ejecute la Extensión de Servicio. Sin un App Group, los medios se almacenan en caché en el directorio tmp de la extensión.

Callbacks de ciclo de vida y análisis

Anchor link to

Establece storiesDelegate para observar los eventos de las historias: impresiones de página, toques de botón, finalización y contenido de respaldo. Adáptate a PushwooshStoriesDelegate; cada método es opcional, así que implementa solo los que necesites.

import PushwooshNotificationUI
class NotificationViewController: PushwooshStoriesViewController, PushwooshStoriesDelegate {
override func viewDidLoad() {
super.viewDidLoad()
storiesDelegate = self
}
func storiesViewController(_ controller: PushwooshStoriesViewController, didStartWithPageCount pageCount: Int) {}
func storiesViewController(_ controller: PushwooshStoriesViewController, didShow page: StoryPage, at index: Int) {}
func storiesViewController(_ controller: PushwooshStoriesViewController, didTapActionFor page: StoryPage, at index: Int) {}
func storiesViewControllerDidFinish(_ controller: PushwooshStoriesViewController) {}
func storiesViewControllerDidShowFallback(_ controller: PushwooshStoriesViewController) {}
}
CallbackCuándo se activa
didStartWithPageCount:Se ha analizado un payload de historias válido y la reproducción está a punto de comenzar.
didShow:at:Una página se ha hecho visible. Úsalo para las impresiones por página.
didTapActionFor:at:El usuario ha tocado el botón de llamada a la acción.
storiesViewControllerDidFinish:La última página ha terminado de reproducirse.
storiesViewControllerDidShowFallback:El payload faltaba o estaba malformado y se ha mostrado el contenido de respaldo.

El StoryPage que se pasa a los callbacks expone los campos imageURL, duration, link, buttonTitle, title y subtitle de la página.

Anchor link to

Toca el tercio derecho de la pantalla para ir a la página siguiente y el tercio izquierdo para retroceder. El deslizamiento horizontal no se utiliza intencionadamente, ya que entra en conflicto con el gesto del sistema para descartar notificaciones. Tocar el botón de la página abre su enlace profundo (deep link) y descarta la notificación.

Referencias

Anchor link to