# Rich media modal para iOS

A partir de la versión 6.7.5 del SDK de Pushwoosh, tienes la capacidad de enviar **Rich Media modales**.

Estamos introduciendo los nuevos **Rich Media modales**, que pueden ser personalizados. Los nuevos Rich Media modales no bloquean completamente la pantalla y pueden posicionarse en diferentes partes de la pantalla (superior, inferior y central).

> Para más información sobre las páginas de Rich Media, por favor consulta [nuestra guía](/es/product/content/rich-media).

## Configuración

<Aside type="note">
 Por defecto, el SDK de Pushwoosh para iOS soporta la visualización de rich media heredados.
</Aside>

<Aside type="note">
Si planeas usar la visualización de rich media modales como mensajes in-app en el Customer Journey Builder, asegúrate de haber implementado el código que se muestra a continuación. Consulta la [integración básica del SDK](/es/developer/pushwoosh-sdk/ios-sdk/setting-up-pushwoosh-ios-sdk/basic-integration-guide/) para más detalles.
</Aside>

```swift
//para notificaciones push silenciosas
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    Pushwoosh.configure.handlePushReceived(userInfo)
    completionHandler(.noData)
}
```

### Opción 1: Configuración de Info.plist

Para habilitar la visualización de Rich Media modales, establece el parámetro `Pushwoosh_RICH_MEDIA_STYLE` en tu **info.plist** y asígnale el valor `MODAL_RICH_MEDIA`.

**Info.plist**:
```xml
<key>Pushwoosh_RICH_MEDIA_STYLE</key>
<string>MODAL_RICH_MEDIA</string>
```

### Opción 2: Configuración programática (SDK 7.0.14+)

<Aside type="tip">
Disponible desde la versión **7.0.14** del SDK de Pushwoosh para iOS.
</Aside>

También puedes configurar el estilo de presentación de Rich Media de forma programática en tu AppDelegate:

<Tabs>
<TabItem label="Swift">
```swift
func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Establecer el estilo de presentación modal
    Pushwoosh.media.setRichMediaPresentationStyle(.modal)

    // Configurar la apariencia de la ventana modal
    Pushwoosh.media.modalRichMedia.configure(
        position: .PWModalWindowPositionBottom,
        presentAnimation: .PWAnimationPresentFromBottom,
        dismissAnimation: .PWAnimationDismissDown
    )

    Pushwoosh.configure.registerForPushNotifications()
    return true
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Establecer el estilo de presentación modal
    [[Pushwoosh media] setRichMediaPresentationStyle:PWRichMediaPresentationStyleModal];

    // Configurar la apariencia de la ventana modal
    [[[Pushwoosh media] modalRichMedia] configureWithPosition:PWModalWindowPositionBottom
                                             presentAnimation:PWAnimationPresentFromBottom
                                             dismissAnimation:PWAnimationDismissDown];

    [[Pushwoosh configure] registerForPushNotifications];
    return YES;
}
```
</TabItem>
</Tabs>

Por defecto, los Rich Media modales se mostrarán en el centro de la pantalla con una animación de aparición de abajo hacia arriba.

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-1.webm" title="Ejemplo" autoplay loop muted playsinline width="300" />
</div>

### Posicionamiento de Rich Media modales

Los Rich Media modales pueden posicionarse en diferentes ubicaciones de la pantalla.

```objective-c
/**
 Enum que define las posibles posiciones para mostrar una ventana modal.

 - `PWModalWindowPositionTop`: La ventana modal aparece en la parte superior de la pantalla, dentro del área segura.
 - `PWModalWindowPositionCenter`: La ventana modal aparece en el centro de la pantalla, dentro del área segura.
 - `PWModalWindowPositionBottom`: La ventana modal aparece en la parte inferior de la pantalla, dentro del área segura.
 - `PWModalWindowPositionBottomSheet`: La ventana modal aparece en la parte más inferior de la pantalla, ignorando el área segura.
 - `PWModalWindowPositionFullScreen`: Pantalla completa, ignora los márgenes del área segura.
 - `PWModalWindowPositionDefault`: La posición por defecto es el centro de la pantalla, dentro del área segura.
 */
typedef NS_ENUM(NSInteger, ModalWindowPosition) {
    PWModalWindowPositionTop,       // Aparece en la parte superior de la pantalla (dentro del área segura)
    PWModalWindowPositionCenter,    // Aparece en el centro de la pantalla (dentro del área segura)
    PWModalWindowPositionBottom,    // Aparece en la parte inferior de la pantalla (dentro del área segura)
    PWModalWindowPositionBottomSheet, // Aparece en la parte más inferior de la pantalla (ignora el área segura)
    PWModalWindowPositionFullScreen, // Pantalla completa, ignora los márgenes del área segura
    PWModalWindowPositionDefault    // Posición por defecto (centro de la pantalla, dentro del área segura)
};
```

El ejemplo a continuación muestra un Rich Media modal en la parte superior de la pantalla.

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-2.webm" title="Ejemplo" autoplay loop muted playsinline width="300" />
</div>

Las animaciones de aparición de Rich Media modales incluyen:

```objective-c
typedef NS_ENUM(NSInteger, PresentModalWindowAnimation) {
    PWAnimationPresentFromBottom,
    PWAnimationPresentFromTop,
    PWAnimationPresentFromRight,
    PWAnimationPresentFromLeft,
    PWAnimationPresentNone
};
```

Las animaciones de cierre de Rich Media modales incluyen:

```objective-c
typedef NS_ENUM(NSInteger, DismissModalWindowAnimation) {
    PWAnimationDismissDown,
    PWAnimationDismissUp,
    PWAnimationDismissLeft,
    PWAnimationDismissRight,
    PWAnimationCurveEaseInOut,
    PWAnimationDismissNone,

    /**
     * La animación de cierre por defecto es `PWAnimationCurveEaseInOut`
     */
    PWAnimationDismissDefault
};
```

El ejemplo a continuación demuestra la visualización de un Rich Media modal en la parte inferior de la pantalla con una animación de aparición de izquierda a derecha y una animación de cierre hacia la derecha:

<div style={{ display: "flex", justifyContent: "center" }}>
<video src="/ios-push-notifications-ios-modal-rich-media-3.webm" title="Ejemplo" autoplay loop muted playsinline width="300" />
</div>

### Parámetros adicionales para Rich Media modales

<Aside type="tip">
La siguiente API está disponible desde la versión **7.0.14** del SDK de Pushwoosh para iOS.
</Aside>

Los parámetros adicionales para mostrar Rich Media modales incluyen opciones como agregar retroalimentación háptica de tipo vibración, habilitar gestos de deslizamiento y establecer un temporizador de cierre automático después de una duración especificada.

<Tabs>
<TabItem label="Swift">
```swift
// Tipo de retroalimentación háptica
Pushwoosh.media.modalRichMedia.setHapticFeedbackType(.PWHapticFeedbackLight)

// Direcciones de deslizamiento para cerrar
Pushwoosh.media.modalRichMedia.setDismissSwipeDirections([
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissDown.rawValue),
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissUp.rawValue)
])

// Establecer el radio de las esquinas del Rich Media
let topCorners = PWCornerTypeTopLeft.rawValue | PWCornerTypeTopRight.rawValue
Pushwoosh.media.modalRichMedia.setCornerType(CornerType(rawValue: topCorners), withRadius: 16)

// Cerrar el Rich Media modal después de N segundos
Pushwoosh.media.modalRichMedia.closeAfter(3)
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
// Tipo de retroalimentación háptica
[[[Pushwoosh media] modalRichMedia] setHapticFeedbackType:PWHapticFeedbackLight];

// Direcciones de deslizamiento para cerrar
[[[Pushwoosh media] modalRichMedia] setDismissSwipeDirections:@[
    @(PWSwipeDismissDown),
    @(PWSwipeDismissUp)
]];

// Establecer el radio de las esquinas del Rich Media
CornerType topCorners = PWCornerTypeTopLeft | PWCornerTypeTopRight;
[[[Pushwoosh media] modalRichMedia] setCornerType:topCorners withRadius:16.0];

// Cerrar el Rich Media modal después de N segundos
[[[Pushwoosh media] modalRichMedia] closeAfter:3.0];
```
</TabItem>
</Tabs>

**Tipos de retroalimentación háptica:**

```objective-c
typedef NS_ENUM(NSInteger, HapticFeedbackType) {
    PWHapticFeedbackLight,         // Retroalimentación de vibración ligera
    PWHapticFeedbackMedium,        // Retroalimentación de vibración media
    PWHapticFeedbackHard,          // Retroalimentación de vibración fuerte
    PWHapticFeedbackNone           // La vibración está desactivada (por defecto)
};
```

**Direcciones de deslizamiento:**

```objective-c
typedef NS_ENUM(NSInteger, DismissSwipeDirection) {
    PWSwipeDismissDown,
    PWSwipeDismissUp,
    PWSwipeDismissLeft,
    PWSwipeDismissRight,
    PWSwipeDismissNone
};
```

## PWRichMediaPresentingDelegate

<Aside type="tip">
La API de delegado a través de `Pushwoosh.media.modalRichMedia.delegate` está disponible desde la versión **7.0.14** del SDK.
</Aside>

Para gestionar la cola de rich media modales, necesitas implementar los métodos de delegado de `PWRichMediaPresentingDelegate`.
Al usar esta funcionalidad, los rich media modales se presentan secuencialmente, y el siguiente no se mostrará hasta que el usuario cierre el actual. Una vez que el usuario cierra el rich media presentado, se mostrará el siguiente, que era parte de una notificación push diferente.

<Tabs>
<TabItem label="Swift">
```swift
import UIKit
import PushwooshFramework

@main
class AppDelegate: UIResponder, UIApplicationDelegate, PWRichMediaPresentingDelegate {

    var richMediaQueue: [PWRichMedia] = []
    var isPresenting = false

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Configurar rich media modales
        Pushwoosh.media.setRichMediaPresentationStyle(.modal)
        Pushwoosh.media.modalRichMedia.configure(
            position: .PWModalWindowPositionBottom,
            presentAnimation: .PWAnimationPresentFromBottom,
            dismissAnimation: .PWAnimationDismissDown
        )

        // Establecer delegado
        Pushwoosh.media.modalRichMedia.delegate = self

        Pushwoosh.configure.registerForPushNotifications()
        return true
    }

    // MARK: - PWRichMediaPresentingDelegate

    func richMediaManager(_ richMediaManager: PWRichMediaManager, shouldPresent richMedia: PWRichMedia) -> Bool {
        if !richMediaQueue.contains(where: { $0 === richMedia }) {
            richMediaQueue.append(richMedia)
        }
        return !isPresenting
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, didPresent richMedia: PWRichMedia) {
        isPresenting = true
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, didClose richMedia: PWRichMedia) {
        isPresenting = false

        if let idx = richMediaQueue.firstIndex(where: { $0 === richMedia }) {
            richMediaQueue.remove(at: idx)
        }

        // Presentar el siguiente rich media en la cola
        if let nextRichMedia = richMediaQueue.first {
            Pushwoosh.media.modalRichMedia.present(nextRichMedia)
        }
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager, presentingDidFailFor richMedia: PWRichMedia, withError error: Error) {
        richMediaManager(richMediaManager, didClose: richMedia)
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import "AppDelegate.h"
#import <PushwooshFramework/PushwooshFramework.h>

@interface AppDelegate () <PWRichMediaPresentingDelegate>

@property (nonatomic, strong) NSMutableArray<PWRichMedia *> *richMediaQueue;
@property (nonatomic, assign) BOOL isPresenting;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.richMediaQueue = [NSMutableArray array];
    self.isPresenting = NO;

    // Configurar rich media modales
    [[Pushwoosh media] setRichMediaPresentationStyle:PWRichMediaPresentationStyleModal];
    [[[Pushwoosh media] modalRichMedia] configureWithPosition:PWModalWindowPositionBottom
                                             presentAnimation:PWAnimationPresentFromBottom
                                             dismissAnimation:PWAnimationDismissDown];

    // Establecer delegado
    [[[Pushwoosh media] modalRichMedia] setDelegate:self];

    [[Pushwoosh configure] registerForPushNotifications];
    return YES;
}

#pragma mark - PWRichMediaPresentingDelegate

- (BOOL)richMediaManager:(PWRichMediaManager *)richMediaManager shouldPresentRichMedia:(PWRichMedia *)richMedia {
    if (![self.richMediaQueue containsObject:richMedia]) {
        [self.richMediaQueue addObject:richMedia];
    }
    return !self.isPresenting;
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didPresentRichMedia:(PWRichMedia *)richMedia {
    self.isPresenting = YES;
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didCloseRichMedia:(PWRichMedia *)richMedia {
    self.isPresenting = NO;

    [self.richMediaQueue removeObject:richMedia];

    // Presentar el siguiente rich media en la cola
    if (self.richMediaQueue.count > 0) {
        [[[Pushwoosh media] modalRichMedia] presentRichMedia:self.richMediaQueue.firstObject];
    }
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager presentingDidFailForRichMedia:(PWRichMedia *)richMedia withError:(NSError *)error {
    [self richMediaManager:richMediaManager didCloseRichMedia:richMedia];
}

@end
```
</TabItem>
</Tabs>