# Rich media modaux pour iOS

À partir de la version 6.7.5 du SDK Pushwoosh, vous avez la possibilité d'envoyer des **Rich Media modaux**.

Nous introduisons de nouveaux **Rich Media modaux**, qui peuvent être personnalisés. Les nouveaux Rich Media modaux ne bloquent pas complètement l'écran et peuvent être positionnés à différents endroits de l'écran (en haut, en bas et au centre).

> Pour plus d'informations sur les pages Rich Media, veuillez consulter [notre guide](/fr/product/content/rich-media).

## Configuration

<Aside type="note">
 Par défaut, le SDK iOS de Pushwoosh prend en charge l'affichage des rich media hérités.
</Aside>

<Aside type="note">
Si vous prévoyez d'utiliser l'affichage de rich media modaux comme messages in-app dans le Customer Journey Builder, assurez-vous d'avoir implémenté le code ci-dessous. Consultez l'[intégration de base du SDK](/fr/developer/pushwoosh-sdk/ios-sdk/setting-up-pushwoosh-ios-sdk/basic-integration-guide/) pour plus de détails.
</Aside>

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

### Option 1 : Configuration via Info.plist

Pour activer l'affichage des Rich Media modaux, définissez le paramètre `Pushwoosh_RICH_MEDIA_STYLE` dans votre fichier **info.plist** et attribuez-lui la valeur `MODAL_RICH_MEDIA`.

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

### Option 2 : Configuration par programmation (SDK 7.0.14+)

<Aside type="tip">
Disponible depuis la version **7.0.14** du SDK iOS de Pushwoosh.
</Aside>

Vous pouvez également configurer le style de présentation des Rich Media par programmation dans votre AppDelegate :

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

    // Set modal presentation style
    Pushwoosh.media.setRichMediaPresentationStyle(.modal)

    // Configure modal window appearance
    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 {

    // Set modal presentation style
    [[Pushwoosh media] setRichMediaPresentationStyle:PWRichMediaPresentationStyleModal];

    // Configure modal window appearance
    [[[Pushwoosh media] modalRichMedia] configureWithPosition:PWModalWindowPositionBottom
                                             presentAnimation:PWAnimationPresentFromBottom
                                             dismissAnimation:PWAnimationDismissDown];

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

Par défaut, les Rich Media modaux seront affichés au centre de l'écran avec une animation d'apparition de bas en haut.

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

### Positionnement des Rich Media modaux

Les Rich Media modaux peuvent être positionnés à différents endroits de l'écran.

```objective-c
/**
 Énumération définissant les positions possibles pour l'affichage d'une fenêtre modale.

 - `PWModalWindowPositionTop` : La fenêtre modale apparaît en haut de l'écran, dans la zone de sécurité.
 - `PWModalWindowPositionCenter` : La fenêtre modale apparaît au centre de l'écran, dans la zone de sécurité.
 - `PWModalWindowPositionBottom` : La fenêtre modale apparaît en bas de l'écran, dans la zone de sécurité.
 - `PWModalWindowPositionBottomSheet` : La fenêtre modale apparaît tout en bas de l'écran, en ignorant la zone de sécurité.
 - `PWModalWindowPositionDefault` : La position par défaut est le centre de l'écran, dans la zone de sécurité.
 */
typedef NS_ENUM(NSInteger, ModalWindowPosition) {
    PWModalWindowPositionTop,       // Apparaît en haut de l'écran (dans la zone de sécurité)
    PWModalWindowPositionCenter,    // Apparaît au centre de l'écran (dans la zone de sécurité)
    PWModalWindowPositionBottom,    // Apparaît en bas de l'écran (dans la zone de sécurité)
    PWModalWindowPositionBottomSheet, // Apparaît tout en bas de l'écran (ignore la zone de sécurité)
    PWModalWindowPositionFullScreen, // Plein écran, ignore les marges de la zone de sécurité
    PWModalWindowPositionDefault    // Position par défaut (centre de l'écran, dans la zone de sécurité)
};
```

L'exemple ci-dessous montre un Rich Media modal affiché en haut de l'écran.

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

Les animations d'affichage des Rich Media modaux incluent :

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

Les animations de fermeture des Rich Media modaux incluent :

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

    /**
     * L'animation de fermeture par défaut est `PWAnimationCurveEaseInOut`
     */
    PWAnimationDismissDefault
};
```

L'exemple ci-dessous montre l'affichage d'un Rich Media modal en bas de l'écran avec une animation d'affichage de gauche à droite et une animation de fermeture vers la droite :

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

### Paramètres supplémentaires pour les Rich Media modaux

<Aside type="tip">
L'API suivante est disponible depuis la version **7.0.14** du SDK iOS de Pushwoosh.
</Aside>

Les paramètres supplémentaires pour l'affichage des Rich Media modaux incluent des options comme l'ajout d'un retour haptique de type vibration, l'activation des gestes de balayage et la configuration d'une minuterie de fermeture automatique après une durée spécifiée.

<Tabs>
<TabItem label="Swift">
```swift
// Haptic Feedback Type
Pushwoosh.media.modalRichMedia.setHapticFeedbackType(.PWHapticFeedbackLight)

// Swipe directions to dismiss
Pushwoosh.media.modalRichMedia.setDismissSwipeDirections([
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissDown.rawValue),
    NSNumber(value: DismissSwipeDirection.PWSwipeDismissUp.rawValue)
])

// Set Rich Media corner radius
let topCorners = PWCornerTypeTopLeft.rawValue | PWCornerTypeTopRight.rawValue
Pushwoosh.media.modalRichMedia.setCornerType(CornerType(rawValue: topCorners), withRadius: 16)

// Close Modal Rich Media after N seconds
Pushwoosh.media.modalRichMedia.closeAfter(3)
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
// Haptic Feedback Type
[[[Pushwoosh media] modalRichMedia] setHapticFeedbackType:PWHapticFeedbackLight];

// Swipe directions to dismiss
[[[Pushwoosh media] modalRichMedia] setDismissSwipeDirections:@[
    @(PWSwipeDismissDown),
    @(PWSwipeDismissUp)
]];

// Set Rich Media corner radius
CornerType topCorners = PWCornerTypeTopLeft | PWCornerTypeTopRight;
[[[Pushwoosh media] modalRichMedia] setCornerType:topCorners withRadius:16.0];

// Close Modal Rich Media after N seconds
[[[Pushwoosh media] modalRichMedia] closeAfter:3.0];
```
</TabItem>
</Tabs>

**Types de retour haptique :**

```objective-c
typedef NS_ENUM(NSInteger, HapticFeedbackType) {
    PWHapticFeedbackLight,         // Retour par vibration légère
    PWHapticFeedbackMedium,        // Retour par vibration moyenne
    PWHapticFeedbackHard,          // Retour par vibration forte
    PWHapticFeedbackNone           // Vibration désactivée (par défaut)
};
```

**Directions de balayage :**

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

## PWRichMediaPresentingDelegate

<Aside type="tip">
L'API de délégué via `Pushwoosh.media.modalRichMedia.delegate` est disponible depuis la version **7.0.14** du SDK.
</Aside>

Pour gérer la file d'attente des rich media modaux, vous devez implémenter les méthodes de délégué de `PWRichMediaPresentingDelegate`.
En utilisant cette fonctionnalité, les rich media modaux sont présentés séquentiellement, et le suivant ne s'affichera pas tant que l'utilisateur n'aura pas fermé l'actuel. Une fois que l'utilisateur ferme le rich media présenté, le suivant, qui faisait partie d'une autre notification push, sera affiché.

<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 {

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

        // Set delegate
        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)
        }

        // Present next rich media in queue
        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;

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

    // Set delegate
    [[[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];

    // Present next rich media in queue
    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>