Passer au contenu

Personnaliser les messages in-app

Découvrez comment personnaliser les messages in-app pour le SDK de Braze. Pour découvrir des techniques de mise en forme avancées, consultez notre tutoriel sur la personnalisation de la mise en forme des messages à l’aide de paires clé-valeur.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devez intégrer le SDK Web de Braze.

Styles personnalisés

Les éléments de l’IU de Braze sont dotés d’un aspect et d’une convivialité par défaut qui créent une expérience de message in-app neutre et visent à assurer la cohérence avec les autres plateformes mobiles Braze. Les styles par défaut de Braze sont définis en CSS dans le SDK de Braze.

Définition d’un style par défaut

En écrasant des styles sélectionnés dans votre application, vous pouvez personnaliser nos types de messages in-app standard avec vos propres images de fond, familles de polices, styles, tailles, animations, et bien plus encore.

Par exemple, ce qui suit est un exemple de remplacement qui entraînera la mise en italique des en-têtes d’un message in-app :

  body .ab-in-app-message .ab-message-header {
    font-style: italic;
  }

Consultez les JSDocs pour plus d’informations.

Personnaliser le z-index

Par défaut, les messages in-app sont affichés en utilisant z-index: 9001. Ceci est configurable en utilisant l’option d’initialisation inAppMessageZIndex dans le cas où votre site web stylise des éléments avec des valeurs plus élevées.

braze.initialize("YOUR-API-KEY", {
    baseUrl: "YOUR-API-ENDPOINT",
    inAppMessageZIndex: 12000
});

Personnaliser la fermeture des messages

Par défaut, lorsqu’un message in-app est affiché, le fait d’appuyer sur la touche Échap ou de cliquer sur l’arrière-plan grisé de la page fermera le message. Configurez l’option d’initialisation requireExplicitInAppMessageDismissal sur true pour empêcher ce comportement et exiger un clic explicite sur un bouton pour fermer les messages.

import * as braze from "@braze/web-sdk";
braze.initialize("YOUR-API-KEY", {
    baseUrl: "YOUR-API-ENDPOINT",
    requireExplicitInAppMessageDismissal: true
});

Personnaliser le moment d’affichage

Pour remplacer le comportement d’affichage par défaut, supprimez les appels à braze.automaticallyShowInAppMessages() et gérez les messages dans braze.subscribeToInAppMessage(). Enregistrez votre rappel avant braze.openSession(), afin de pouvoir intercepter les messages de début de session et décider d’afficher ou de différer chaque message.

Par défaut, Braze affiche les messages in-app lorsqu’ils sont déclenchés et éligibles à l’affichage. Si vous avez besoin d’un comportement différent pour votre expérience sur l’application, utilisez un rappel personnalisé pour différer ou afficher les messages selon votre propre logique.

L’exemple suivant montre comment s’abonner aux messages in-app déclenchés, différer certains messages et afficher les messages différés ultérieurement :

import * as braze from "@braze/web-sdk";

braze.initialize("YOUR-API-KEY", {
    baseUrl: "YOUR-API-ENDPOINT"
});

braze.subscribeToInAppMessage(function (message) {
    // Control-group messages should always be "shown" to log analytics.
    if (message.isControl || message instanceof braze.ControlMessage) {
        braze.showInAppMessage(message);
        return;
    }

    const shouldDefer = true; // Replace with your own display logic

    if (shouldDefer) {
        braze.deferInAppMessage(message);
        return;
    }

    braze.showInAppMessage(message);
});

braze.openSession();

// Later, when your app is ready to display a deferred message:
const deferredMessage = braze.getDeferredInAppMessage();
if (deferredMessage) {
    braze.showInAppMessage(deferredMessage);
}

Pour des conseils connexes sur la personnalisation de la réception, consultez :

Pour configurer les liens de vos messages in-app afin qu’ils s’ouvrent dans un nouvel onglet, définissez l’option openInAppMessagesInNewTab sur true pour forcer tous les liens issus des clics sur les messages in-app à s’ouvrir dans un nouvel onglet ou une nouvelle fenêtre.

braze.initialize('api-key', { openInAppMessagesInNewTab: true} );

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Android de Braze. Il vous sera également nécessaire de configurer les messages in-app.

Configurer des listeners de gestionnaire personnalisés

Bien que le listener BrazeInAppMessageManager puisse gérer automatiquement l’affichage et le cycle de vie des messages in-app, vous devrez implémenter un listener de gestionnaire personnalisé si vous souhaitez personnaliser entièrement vos messages.

Le SDK Braze dispose d’une classe DefaultHtmlInAppMessageActionListener par défaut, utilisée lorsqu’aucun listener personnalisé n’est défini, et qui effectue automatiquement les actions appropriées. Si vous avez besoin de plus de contrôle sur la façon dont un utilisateur interagit avec les différents boutons à l’intérieur d’un message in-app HTML personnalisé, implémentez une classe IHtmlInAppMessageActionListener personnalisée.

Ce listener s’applique à la fois aux messages créés avec du HTML personnalisé et aux messages créés à l’aide de l’éditeur par glisser-déposer (DnD). Il ne s’applique pas aux IAM traditionnels. Les IAM traditionnels sont les types de messages intégrés de Braze, rendus par le SDK (par exemple, les contextuels, les fenêtres modales et les messages plein écran), créés dans le compositeur de messages in-app d’origine à l’aide de mises en page prédéfinies. Contrairement aux IAM HTML personnalisés et DnD, ils ne passent pas par le flux du listener d’actions HTML.

Si vous définissez un IHtmlInAppMessageActionListener personnalisé, sa logique remplacera le comportement de clic par défaut pour tous les messages DnD. Assurez-vous que votre équipe marketing en est informée, car cela pourrait affecter leurs Campaigns de manière inattendue.

Étape 1 : Implémenter le listener de gestionnaire personnalisé

Étape 1.1 : Implémenter IInAppMessageManagerListener

Créez une classe qui implémente IInAppMessageManagerListener.

Les rappels de votre IInAppMessageManagerListener seront également appelés à différents moments du cycle de vie du message in-app. Par exemple, si vous définissez un listener de gestionnaire personnalisé lorsqu’un message in-app est reçu de Braze, la méthode beforeInAppMessageDisplayed() sera appelée. Si votre implémentation de cette méthode renvoie InAppMessageOperation.DISCARD, cela indique à Braze que le message in-app sera géré par l’application hôte et ne devra pas être affiché par Braze. Si InAppMessageOperation.DISPLAY_NOW est renvoyé, Braze tentera d’afficher le message in-app. Cette méthode doit être utilisée si vous choisissez d’afficher le message in-app de manière personnalisée.

IInAppMessageManagerListener inclut également des méthodes de délégation pour les clics sur les messages et les boutons, qui peuvent être utilisées dans des cas tels que l’interception d’un message lorsqu’un bouton ou un message est cliqué pour un traitement supplémentaire.

Étape 1.2 : Se connecter aux méthodes du cycle de vie de la vue IAM (facultatif)

L’interface IInAppMessageManagerListener possède des méthodes de vue de message in-app appelées à des moments distincts du cycle de vie de la vue du message in-app. Ces méthodes sont appelées dans l’ordre suivant :

  1. beforeInAppMessageViewOpened : appelée juste avant que le message in-app ne soit ajouté à la vue de l’activité. Le message in-app n’est pas encore visible pour l’utilisateur à ce moment.
  2. afterInAppMessageViewOpened : appelée juste après que le message in-app a été ajouté à la vue de l’activité. Le message in-app est désormais visible pour l’utilisateur.
  3. beforeInAppMessageViewClosed : appelée juste avant que le message in-app ne soit retiré de la vue de l’activité. Le message in-app est encore visible pour l’utilisateur à ce moment.
  4. afterInAppMessageViewClosed : appelée juste après que le message in-app a été retiré de la vue de l’activité. Le message in-app n’est plus visible pour l’utilisateur à ce moment.

Notez que l’intervalle entre afterInAppMessageViewOpened et beforeInAppMessageViewClosed correspond au moment où la vue du message in-app est affichée à l’écran et visible pour l’utilisateur.

Créez une classe qui implémente IHtmlInAppMessageActionListener.

Les rappels de votre IHtmlInAppMessageActionListener seront appelés chaque fois que l’utilisateur initie l’une des actions suivantes à l’intérieur du message in-app HTML :

  • Clic sur le bouton de fermeture
  • Déclenchement d’un événement personnalisé
  • Clic sur une URL à l’intérieur du message in-app HTML
public class CustomHtmlInAppMessageActionListener implements IHtmlInAppMessageActionListener {
  private final Context mContext;

  public CustomHtmlInAppMessageActionListener(Context context) {
    mContext = context;
  }

  @Override
  public void onCloseClicked(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show();
    BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
  }

  @Override
  public boolean onCustomEventFired(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show();
    return true;
  }

  @Override
  public boolean onOtherUrlAction(IInAppMessage inAppMessage, String url, Bundle queryBundle) {
    Toast.makeText(mContext, "Custom url pressed: " + url + " . Ignoring", Toast.LENGTH_LONG).show();
    BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false);
    return true;
  }
}
class CustomHtmlInAppMessageActionListener(private val mContext: Context) : IHtmlInAppMessageActionListener {

    override fun onCloseClicked(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle) {
        Toast.makeText(mContext, "HTML In App Message closed", Toast.LENGTH_LONG).show()
        BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
    }

    override fun onCustomEventFired(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom event fired. Ignoring.", Toast.LENGTH_LONG).show()
        return true
    }

    override fun onOtherUrlAction(inAppMessage: IInAppMessage, url: String, queryBundle: Bundle): Boolean {
        Toast.makeText(mContext, "Custom url pressed: $url . Ignoring", Toast.LENGTH_LONG).show()
        BrazeInAppMessageManager.getInstance().hideCurrentlyDisplayingInAppMessage(false)
        return true
    }
}

Étape 2 : Indiquer à Braze d’utiliser le listener de gestionnaire personnalisé

Après avoir créé votre IInAppMessageManagerListener, appelez BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener() pour indiquer à BrazeInAppMessageManager d’utiliser votre IInAppMessageManagerListener personnalisé au lieu du listener par défaut. Faites-le dans votre Application.onCreate() avant tout autre appel à Braze, afin que le listener personnalisé soit défini avant l’affichage de tout message in-app.

Modifier les messages in-app avant l’affichage

Lorsqu’un nouveau message in-app est reçu et qu’un message in-app est déjà affiché, le nouveau message sera placé en haut de la pile et pourra être affiché ultérieurement.

Cependant, s’il n’y a aucun message in-app affiché, la méthode de délégation suivante de IInAppMessageManagerListener sera appelée :

@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  return InAppMessageOperation.DISPLAY_NOW;
}
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  return InAppMessageOperation.DISPLAY_NOW
}

La valeur de retour InAppMessageOperation() permet de contrôler quand le message doit être affiché. L’utilisation suggérée de cette méthode consiste à retarder les messages dans certaines parties de l’application en renvoyant DISPLAY_LATER lorsque les messages in-app perturberaient l’expérience utilisateur sur l’application.

Valeur de retour InAppMessageOperation Comportement
DISPLAY_NOW Le message sera affiché
DISPLAY_LATER Le message sera renvoyé dans la pile et affiché à la prochaine opportunité disponible
DISCARD Le message sera supprimé
null Le message sera ignoré. Cette méthode ne devrait PAS renvoyer null

Consultez InAppMessageOperation pour plus de détails.

Sur Android, cela se fait en appelant logClick et logImpression sur les messages in-app et logButtonClick sur les messages in-app immersifs.

Après avoir créé votre IHtmlInAppMessageActionListener, appelez BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener() pour indiquer à BrazeInAppMessageManager d’utiliser votre IHtmlInAppMessageActionListener personnalisé au lieu du listener d’actions par défaut.

Nous vous recommandons de définir votre IHtmlInAppMessageActionListener dans votre Application.onCreate() avant tout autre appel à Braze. Cela permettra de définir le listener d’actions personnalisé avant l’affichage de tout message in-app :

BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(new CustomHtmlInAppMessageActionListener(context));
BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener(CustomHtmlInAppMessageActionListener(context))

Configurer des factories personnalisées

Vous pouvez remplacer un certain nombre de comportements par défaut à l’aide d’objets factory personnalisés. Ceux-ci peuvent être enregistrés auprès du SDK Braze selon vos besoins pour obtenir les résultats souhaités. Toutefois, si vous décidez de remplacer une factory, vous devrez probablement renvoyer explicitement au comportement par défaut ou ré-implémenter la fonctionnalité fournie par la factory Braze par défaut. L’extrait de code suivant illustre comment fournir des implémentations personnalisées des interfaces IInAppMessageViewFactory et IInAppMessageViewWrapperFactory.

Types de messages in-app

class BrazeDemoApplication : Application(){
 override fun onCreate() {
    super.onCreate()
    registerActivityLifecycleCallbacks(BrazeActivityLifecycleCallbackListener(true, true))
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapperFactory())
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(CustomInAppMessageViewFactory())
  }
}

Types de messages in-app

public class BrazeDemoApplication extends Application {
  @Override
  public void onCreate{
    super.onCreate();
    registerActivityLifecycleCallbacks(new BrazeActivityLifecycleCallbackListener(true, true));
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapperFactory());
    BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory(new CustomInAppMessageViewFactory());
  }
}

Les types de messages in-app de Braze sont suffisamment polyvalents pour couvrir la plupart des cas d’usage personnalisés. Cependant, si vous souhaitez définir entièrement l’apparence visuelle de vos messages in-app au lieu d’utiliser un type par défaut, Braze rend cela possible en configurant une factory de vues personnalisée.

Le BrazeInAppMessageManager gère automatiquement le placement du modèle de message in-app dans la hiérarchie de vues de l’activité existante par défaut en utilisant DefaultInAppMessageViewWrapper. Si vous devez personnaliser la façon dont les messages in-app sont placés dans la hiérarchie de vues, vous devez utiliser une IInAppMessageViewWrapperFactory personnalisée.

Les messages in-app ont des comportements d’animation prédéfinis. Les messages de type Slideup glissent à l’écran ; les messages de type full et modal apparaissent et disparaissent en fondu. Si vous souhaitez définir des comportements d’animation personnalisés pour vos messages in-app, Braze rend cela possible en configurant une factory d’animation personnalisée.

Étape 1 : Implémenter la factory

Créez une classe qui implémente IInAppMessageViewFactory :

public class CustomInAppMessageViewFactory implements IInAppMessageViewFactory {
  @Override
  public View createInAppMessageView(Activity activity, IInAppMessage inAppMessage) {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    switch (inAppMessage.getMessageType()) {
      case SLIDEUP:
      case MODAL:
      case FULL:
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView();
      default:
        // Use the default in-app message factories
        final IInAppMessageViewFactory defaultInAppMessageViewFactory = BrazeInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage);
        return defaultInAppMessageViewFactory.createInAppMessageView(activity, inAppMessage);
    }
  }
}
class CustomInAppMessageViewFactory : IInAppMessageViewFactory {
  override fun createInAppMessageView(activity: Activity, inAppMessage: IInAppMessage): View {
    // Uses a custom view for slideups, modals, and full in-app messages.
    // HTML in-app messages and any other types will use the Braze default in-app message view factories
    when (inAppMessage.messageType) {
      MessageType.SLIDEUP, MessageType.MODAL, MessageType.FULL ->
        // Use a custom view of your choosing
        return createMyCustomInAppMessageView()
      else -> {
        // Use the default in-app message factories
        val defaultInAppMessageViewFactory = BrazeInAppMessageManager.getInstance().getDefaultInAppMessageViewFactory(inAppMessage)
        return defaultInAppMessageViewFactory!!.createInAppMessageView(activity, inAppMessage)
      }
    }
  }
}

Créez une classe qui implémente IInAppMessageViewWrapperFactory et renvoie un IInAppMessageViewWrapper.

Cette factory est appelée immédiatement après la création de la vue du message in-app. La façon la plus simple d’implémenter un IInAppMessageViewWrapper personnalisé est d’étendre le DefaultInAppMessageViewWrapper par défaut :

public class CustomInAppMessageViewWrapper extends DefaultInAppMessageViewWrapper {
  public CustomInAppMessageViewWrapper(View inAppMessageView,
                                       IInAppMessage inAppMessage,
                                       IInAppMessageViewLifecycleListener inAppMessageViewLifecycleListener,
                                       BrazeConfigurationProvider brazeConfigurationProvider,
                                       Animation openingAnimation,
                                       Animation closingAnimation, View clickableInAppMessageView) {
    super(inAppMessageView,
        inAppMessage,
        inAppMessageViewLifecycleListener,
        brazeConfigurationProvider,
        openingAnimation,
        closingAnimation,
        clickableInAppMessageView);
  }

  @Override
  public void open(@NonNull Activity activity) {
    super.open(activity);
    Toast.makeText(activity.getApplicationContext(), "Opened in-app message", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void close() {
    super.close();
    Toast.makeText(mInAppMessageView.getContext().getApplicationContext(), "Closed in-app message", Toast.LENGTH_SHORT).show();
  }
}
class CustomInAppMessageViewWrapper(inAppMessageView: View,
                                    inAppMessage: IInAppMessage,
                                    inAppMessageViewLifecycleListener: IInAppMessageViewLifecycleListener,
                                    brazeConfigurationProvider: BrazeConfigurationProvider,
                                    openingAnimation: Animation,
                                    closingAnimation: Animation, clickableInAppMessageView: View) :
    DefaultInAppMessageViewWrapper(inAppMessageView,
        inAppMessage,
        inAppMessageViewLifecycleListener,
        brazeConfigurationProvider,
        openingAnimation,
        closingAnimation,
        clickableInAppMessageView) {

  override fun open(activity: Activity) {
    super.open(activity)
    Toast.makeText(activity.applicationContext, "Opened in-app message", Toast.LENGTH_SHORT).show()
  }

  override fun close() {
    super.close()
    Toast.makeText(mInAppMessageView.context.applicationContext, "Closed in-app message", Toast.LENGTH_SHORT).show()
  }
}

Créez une classe qui implémente IInAppMessageAnimationFactory :

public class CustomInAppMessageAnimationFactory implements IInAppMessageAnimationFactory {

  @Override
  public Animation getOpeningAnimation(IInAppMessage inAppMessage) {
    Animation animation = new AlphaAnimation(0, 1);
    animation.setInterpolator(new AccelerateInterpolator());
    animation.setDuration(2000L);
    return animation;
  }

  @Override
  public Animation getClosingAnimation(IInAppMessage inAppMessage) {
    Animation animation = new AlphaAnimation(1, 0);
    animation.setInterpolator(new DecelerateInterpolator());
    animation.setDuration(2000L);
    return animation;
  }
}
class CustomInAppMessageAnimationFactory : IInAppMessageAnimationFactory {
  override fun getOpeningAnimation(inAppMessage: IInAppMessage): Animation {
    val animation: Animation = AlphaAnimation(0, 1)
    animation.interpolator = AccelerateInterpolator()
    animation.duration = 2000L
    return animation
  }

  override fun getClosingAnimation(inAppMessage: IInAppMessage): Animation {
    val animation: Animation = AlphaAnimation(1, 0)
    animation.interpolator = DecelerateInterpolator()
    animation.duration = 2000L
    return animation
  }
}

Étape 2 : Demander à Braze d’utiliser la factory

Une fois votre IInAppMessageViewFactory créée, appelez BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory() pour demander à BrazeInAppMessageManager d’utiliser votre IInAppMessageViewFactory personnalisée au lieu de la factory de vues par défaut.

Fonctionnement

La vue de message in-app de type slideup implémente IInAppMessageView. Les vues de messages de type full et modal implémentent IInAppMessageImmersiveView. L’implémentation de l’une de ces classes permet à Braze d’ajouter des écouteurs de clic à votre vue personnalisée le cas échéant. Toutes les classes de vues Braze étendent la classe View d’Android.

L’implémentation de IInAppMessageView vous permet de définir une partie spécifique de votre vue personnalisée comme cliquable. L’implémentation de IInAppMessageImmersiveView vous permet de définir des vues de boutons de message et une vue de bouton de fermeture.

Une fois votre IInAppMessageViewWrapper créé, appelez BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory() pour demander à BrazeInAppMessageManager d’utiliser votre IInAppMessageViewWrapperFactory personnalisée au lieu de la factory de wrappers de vues par défaut.

Nous vous recommandons de configurer votre IInAppMessageViewWrapperFactory dans votre Application.onCreate() avant tout autre appel à Braze. Cela permet de définir la factory de wrappers de vues personnalisée avant l’affichage de tout message in-app :

BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(new CustomInAppMessageViewWrapper());
BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory(CustomInAppMessageViewWrapper())

Une fois votre IInAppMessageAnimationFactory créée, appelez BrazeInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory() pour demander à BrazeInAppMessageManager d’utiliser votre IInAppMessageAnimationFactory personnalisée au lieu de la factory d’animation par défaut.

Nous vous recommandons de configurer votre IInAppMessageAnimationFactory dans votre Application.onCreate() avant tout autre appel à Braze. Cela permet de définir la factory d’animation personnalisée avant l’affichage de tout message in-app.

Styles personnalisés

Les éléments d’interface de Braze sont livrés avec un aspect par défaut qui correspond aux directives standard de l’interface utilisateur Android et offre une expérience fluide. Cet article de référence couvre la personnalisation du style des messages in-app pour votre application Android ou FireOS.

Définir un style par défaut

Vous pouvez consulter les styles par défaut dans le fichier styles.xml du SDK de Braze :

  <style name="Braze"/>
  <style name="Braze.InAppMessage"/>
  <style name="Braze.InAppMessage.Header">
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_width">match_parent</item>
    <item name="android:padding">0.0dp</item>
    <item name="android:background">@android:color/transparent</item>
    <item name="android:textColor">@color/com_braze_inappmessage_header_text</item>
    <item name="android:textSize">20.0sp</item>
    <item name="android:lineSpacingMultiplier">1.3</item>
    <item name="android:gravity">center</item>
    <item name="android:textStyle">bold</item>
    <item name="android:layout_centerHorizontal">true</item>
  </style>

Si vous le souhaitez, vous pouvez remplacer ces styles pour créer un aspect qui correspond mieux à votre application.

Pour remplacer un style, copiez-le dans son intégralité dans le fichier styles.xml de votre projet et apportez vos modifications. Le style complet doit être copié dans votre fichier local styles.xml pour que tous les attributs soient correctement définis. Notez que ces styles personnalisés s’appliquent aux modifications d’éléments individuels de l’interface utilisateur, et non aux changements globaux de mise en page. Les changements au niveau de la mise en page doivent être gérés avec des vues personnalisées.

Personnaliser la police

Vous pouvez définir une police personnalisée en localisant la police dans le répertoire res/font. Pour l’utiliser, remplacez le style du texte du message, des en-têtes et du texte des boutons et utilisez l’attribut fontFamily pour indiquer à Braze d’utiliser votre famille de polices personnalisée.

Par exemple, pour mettre à jour la police du texte des boutons de votre message in-app, remplacez le style Braze.InAppMessage.Button et référencez votre famille de polices personnalisée. La valeur de l’attribut doit pointer vers une famille de polices dans votre répertoire res/font.

Voici un exemple tronqué avec une famille de polices personnalisée, my_custom_font_family, référencée à la dernière ligne :

  <style name="Braze.InAppMessage.Button">
    <item name="android:layout_height">wrap_content</item>
    ...
    <item name="android:paddingBottom">15.0dp</item>
    <item name="android:fontFamily">@font/my_custom_font_family</item>
    <item name="fontFamily">@font/my_custom_font_family</item>
  </style>

En plus du style Braze.InAppMessage.Button pour le texte des boutons, le style pour le texte du message est Braze.InAppMessage.Message et le style pour les en-têtes du message est Braze.InAppMessage.Header. Si vous souhaitez utiliser votre famille de polices personnalisée sur l’ensemble du texte possible des messages in-app, vous pouvez définir votre famille de polices sur le style Braze.InAppMessage, qui est le style parent de tous les messages in-app.

Fermeture des messages

Balayer pour fermer les messages contextuels

Par défaut, les messages in-app de type contextuel peuvent être fermés par un geste de balayage. La direction du balayage dépend de la position du message contextuel :

  • Balayage vers la gauche ou la droite : Ferme le message contextuel quelle que soit sa position.
  • Message contextuel depuis le bas : Un balayage de haut en bas ferme le message. Un balayage de bas en haut ne le ferme pas.
  • Message contextuel depuis le haut : Un balayage de bas en haut ferme le message. Un balayage de haut en bas ne le ferme pas.

Ce comportement de balayage est intégré dans le wrapper par défaut DefaultInAppMessageViewWrapper et ne s’applique qu’aux messages in-app de type contextuel. Les messages in-app modaux et plein écran ne prennent pas en charge la fermeture par balayage. Pour personnaliser ce comportement, vous pouvez implémenter une factory de wrapper de vue personnalisée.

Désactiver la fermeture par le bouton retour

Par défaut, le bouton retour matériel ferme les messages in-app de Braze. Ce comportement peut être désactivé message par message via BrazeInAppMessageManager.setBackButtonDismissesInAppMessageView().

Dans l’exemple suivant, disable_back_button est une paire clé-valeur personnalisée définie sur le message in-app qui indique si le message doit autoriser le bouton retour à le fermer :

BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener(new DefaultInAppMessageManagerListener() {
  @Override
  public void beforeInAppMessageViewOpened(View inAppMessageView, IInAppMessage inAppMessage) {
    super.beforeInAppMessageViewOpened(inAppMessageView, inAppMessage);
    final Map<String, String> extras = inAppMessage.getExtras();
    if (extras != null && extras.containsKey("disable_back_button")) {
      BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(false);
    }
  }

  @Override
  public void afterInAppMessageViewClosed(IInAppMessage inAppMessage) {
    super.afterInAppMessageViewClosed(inAppMessage);
    BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(true);
  }
});
BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener(object : DefaultInAppMessageManagerListener() {
  override fun beforeInAppMessageViewOpened(inAppMessageView: View, inAppMessage: IInAppMessage) {
    super.beforeInAppMessageViewOpened(inAppMessageView, inAppMessage)
    val extras = inAppMessage.extras
    if (extras != null && extras.containsKey("disable_back_button")) {
      BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(false)
    }
  }

  override fun afterInAppMessageViewClosed(inAppMessage: IInAppMessage) {
    super.afterInAppMessageViewClosed(inAppMessage)
    BrazeInAppMessageManager.getInstance().setBackButtonDismissesInAppMessageView(true)
  }
})

Activer la fermeture par appui en dehors

Par défaut, la fermeture du message modal par un appui en dehors est définie sur false. Définir cette valeur sur true entraînera la fermeture du message in-app modal lorsque l’utilisateur appuie en dehors du message in-app. Ce comportement peut être activé en appelant :

BrazeInAppMessageManager.getInstance().setClickOutsideModalViewDismissInAppMessageView(true)

Personnaliser l’orientation

Pour définir une orientation fixe pour un message in-app, commencez par configurer un écouteur de gestionnaire de messages in-app personnalisé. Ensuite, mettez à jour l’orientation sur l’objet IInAppMessage dans la méthode déléguée beforeInAppMessageDisplayed() :

public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Set the orientation to portrait
  inAppMessage.setOrientation(Orientation.PORTRAIT);
  return InAppMessageOperation.DISPLAY_NOW;
}
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  // Set the orientation to portrait
  inAppMessage.orientation = Orientation.PORTRAIT
  return InAppMessageOperation.DISPLAY_NOW
}

Pour les tablettes, les messages in-app s’affichent dans le style d’orientation préféré de l’utilisateur, quelle que soit l’orientation réelle de l’écran.

Désactiver le thème sombre

Par défaut, la méthode beforeInAppMessageDisplayed() de IInAppMessageManagerListener vérifie les paramètres système et active conditionnellement le thème sombre sur le message à l’aide du code suivant :

@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  if (inAppMessage instanceof IInAppMessageThemeable && ViewUtils.isDeviceInNightMode(BrazeInAppMessageManager.getInstance().getApplicationContext())) {
    ((IInAppMessageThemeable) inAppMessage).enableDarkTheme();
  }
  return InAppMessageOperation.DISPLAY_NOW;
}
override fun beforeInAppMessageDisplayed(inAppMessage: IInAppMessage): InAppMessageOperation {
  if (inAppMessage is IInAppMessageThemeable && ViewUtils.isDeviceInNightMode(BrazeInAppMessageManager.getInstance().applicationContext!!)) {
    (inAppMessage as IInAppMessageThemeable).enableDarkTheme()
  }
  return InAppMessageOperation.DISPLAY_NOW
}

Pour modifier ce comportement, vous pouvez appeler enableDarkTheme à n’importe quelle étape du processus de pré-affichage afin d’implémenter votre propre logique conditionnelle.

Personnaliser l’invite d’avis Google Play

En raison des limitations et restrictions imposées par Google, les invites d’avis Google Play personnalisées ne sont pas actuellement prises en charge par Braze. Bien que certains utilisateurs aient réussi à intégrer ces invites, d’autres ont obtenu de faibles taux de réussite en raison des quotas de Google Play. L’intégration se fait à vos propres risques. Consultez la documentation sur les invites d’avis in-app de Google Play.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Braze Swift.

Configuration du délégué d’interface utilisateur (obligatoire)

Pour personnaliser la présentation des messages in-app et réagir aux différents événements du cycle de vie, vous devez configurer BrazeInAppMessageUIDelegate. Il s’agit d’un protocole de délégué utilisé pour recevoir et traiter les payloads de messages in-app déclenchés, recevoir les événements du cycle de vie de l’affichage et contrôler le timing d’affichage. Pour utiliser BrazeInAppMessageUIDelegate, vous devez :

  • Utiliser l’implémentation par défaut BrazeInAppMessageUI comme votre inAppMessagePresenter.
  • Inclure la bibliothèque BrazeUI dans votre projet.

Étape 1 : Implémenter le protocole BrazeInAppMessageUIDelegate

Commencez par implémenter le protocole BrazeInAppMessageUIDelegate et toutes les méthodes correspondantes souhaitées. Dans l’exemple suivant, ce protocole est implémenté dans la classe AppDelegate de l’application.

extension AppDelegate: BrazeInAppMessageUIDelegate {
  // Implement your protocol methods here.
}
@interface AppDelegate () <BrazeInAppMessageUIDelegate>

@end

@implementation AppDelegate
  // Implement your protocol methods here.
@end

Étape 2 : Assigner l’objet delegate

Assignez l’objet delegate sur l’instance BrazeInAppMessageUI avant d’assigner cette interface utilisateur de message in-app comme votre inAppMessagePresenter.

let inAppMessageUI = BrazeInAppMessageUI()
inAppMessageUI.delegate = self
AppDelegate.braze?.inAppMessagePresenter = inAppMessageUI
BrazeInAppMessageUI *inAppMessageUI = [[BrazeInAppMessageUI alloc] init];
inAppMessageUI.delegate = self;
AppDelegate.braze.inAppMessagePresenter = inAppMessageUI;

Comportement au clic

Chaque objet Braze.InAppMessage contient une ClickAction correspondante, qui définit le comportement lors du clic.

Types d’actions au clic

La propriété clickAction de votre Braze.InAppMessage est définie par défaut sur .none, mais peut être configurée avec l’une des valeurs suivantes :

ClickAction Comportement au clic
.url(URL, useWebView: Bool) Ouvre l’URL donnée dans un navigateur externe. Si useWebView est défini sur true, l’URL s’ouvrira dans une vue web.
.none Le message sera fermé lorsqu’il est cliqué.

Personnaliser le comportement au clic

Pour personnaliser ce comportement, vous pouvez modifier la propriété clickAction en vous référant à l’exemple suivant :

func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  if let newUrl = URL(string: "{your-url}") {
    context.message.clickAction = .url(newUrl, useWebView: true)
  }
}

La méthode inAppMessage(_:prepareWith:) n’est pas disponible en Objective-C.

Gérer le comportement personnalisé

La méthode déléguée BrazeInAppMessageUIDelegate suivante est appelée lorsqu’un utilisateur clique sur un message in-app. Ce rappel est déclenché pour les clics initiés par l’utilisateur sur les boutons de messages in-app et les boutons de messages in-app HTML (liens), et un identifiant de bouton est fourni en tant que paramètre optionnel pour ces interactions. Ce rappel n’est pas invoqué pour les clics programmatiques déclenchés via brazeBridge.logClick().

func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  shouldProcess clickAction: Braze.InAppMessage.ClickAction,
  buttonId: String?,
  message: Braze.InAppMessage,
  view: InAppMessageView
) -> Bool
- (BOOL)inAppMessage:(BrazeInAppMessageUI *)ui
       shouldProcess:(enum BRZInAppMessageRawClickAction)clickAction
                 url:(NSURL *)uri
            buttonId:(NSString *)buttonId
             message:(BRZInAppMessageRaw *)message
                view:(UIView *)view;

Cette méthode renvoie une valeur booléenne pour indiquer si Braze doit continuer à exécuter l’action au clic.

func inAppMessage(
  _ ui: BrazeInAppMessageUI, shouldProcess clickAction: Braze.InAppMessage.ClickAction,
  buttonId: String?, message: Braze.InAppMessage, view: InAppMessageView
) -> Bool {
    guard let buttonId,
      let idInt = Int(buttonId)
    else { return true }
    var button: BrazeKit.Braze.InAppMessage.Button? = nil

    switch message {
    case .modal(let modal):
      button = modal.buttons[idInt]

    case .modalImage(let modalImage):
      button = modalImage.buttons[idInt]

    case .full(let full):
      button = full.buttons[idInt]

    case .fullImage(let fullImage):
      button = fullImage.buttons[idInt]

    default:
      break
    }

    print(button?.id)
    print(button?.text)
    print(button?.clickAction)

    return true
  }
- (BOOL)inAppMessage:(BrazeInAppMessageUI *)ui
       shouldProcess:(enum BRZInAppMessageRawClickAction)clickAction
                 url:(NSURL *)uri
            buttonId:(NSString *)buttonId
             message:(BRZInAppMessageRaw *)message
                view:(UIView *)view {
  NSInteger buttonInt = [buttonId integerValue];

  if (message.type == BRZInAppMessageRawTypeFull || message.type == BRZInAppMessageRawTypeModal) {
    BRZInAppMessageRawButton *button = message.buttons[buttonInt];
    NSLog(@"%ld", (long)button.identifier);
    NSLog(@"%@", button.text);
    NSLog(@"%ld", (long)button.clickAction);
  }
  return YES;
}

Balayer pour fermer les messages contextuels

Par défaut, les messages in-app contextuels peuvent être fermés par un geste de balayage. La direction du balayage dépend de la position du message contextuel :

  • Balayage vers la gauche ou la droite : Ferme le message contextuel, quelle que soit sa position.
  • Message contextuel depuis le bas : Un balayage du haut vers le bas ferme le message. Un balayage du bas vers le haut ne le ferme pas.
  • Message contextuel depuis le haut : Un balayage du bas vers le haut ferme le message. Un balayage du haut vers le bas ne le ferme pas.

Ce comportement de balayage est intégré à la vue par défaut SlideupView de BrazeInAppMessageUI et s’applique uniquement aux messages in-app contextuels. Les messages in-app modaux et plein écran ne prennent pas en charge la fermeture par balayage. Pour personnaliser davantage la vue contextuelle, y compris le comportement de balayage, vous pouvez modifier les SlideupView.Attributes ou fournir une vue personnalisée via le sous-classement.

Personnaliser la fermeture des fenêtres modales

Pour activer la fermeture par un appui en dehors de la fenêtre, vous pouvez modifier la propriété dismissOnBackgroundTap dans la structure Attributes du type de message in-app que vous souhaitez personnaliser.

Par exemple, si vous souhaitez activer cette fonctionnalité pour les messages in-app d’image modale, vous pouvez configurer ce qui suit :

BrazeInAppMessageUI.ModalImageView.Attributes.defaults.dismissOnBackgroundTap = true

La personnalisation via Attributes n’est pas disponible en Objective-C.

La valeur par défaut est false. Cela détermine si le message in-app modal sera fermé lorsque l’utilisateur appuie en dehors du message in-app.

DismissModalOnOutsideTap Description
true Les messages in-app modaux seront fermés lors d’un appui en dehors de la fenêtre.
false Valeur par défaut : les messages in-app modaux ne seront pas fermés lors d’un appui en dehors de la fenêtre.

Pour plus de détails sur la personnalisation des messages in-app, consultez cet article.

Personnaliser l’orientation des messages

Vous pouvez personnaliser l’orientation de vos messages in-app. Vous pouvez définir une nouvelle orientation par défaut pour tous les messages ou définir une orientation personnalisée pour un seul message.

Pour choisir une orientation par défaut pour tous les messages in-app, utilisez la méthode inAppMessage(_:prepareWith:) afin de définir la propriété preferredOrientation sur le PresentationContext.

Par exemple, pour définir le mode portrait comme orientation par défaut :

func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  context.preferredOrientation = .portrait
}
- (void)inAppMessage:(BrazeInAppMessageUI *)ui
         prepareWith:(BrazeInAppMessageUIPresentationContextRaw *)context {
  context.preferredOrientation = BRZInAppMessageRawOrientationPortrait;
}

Pour définir l’orientation d’un seul message, modifiez la propriété orientation de Braze.InAppMessage :

// Set inAppMessage orientation to support any configuration
inAppMessage.orientation = .any

// Set inAppMessage orientation to only display in portrait
inAppMessage.orientation = .portrait

// Set inAppMessage orientation to only display in landscape
inAppMessage.orientation = .landscape
// Set inAppMessage orientation to support any configuration
inAppMessage.orientation = BRZInAppMessageRawOrientationAny;

// Set inAppMessage orientation to only display in portrait
inAppMessage.orientation = BRZInAppMessageRawOrientationPortrait;

// Set inAppMessage orientation to only display in landscape
inAppMessage.orientation = BRZInAppMessageRawOrientationLandscape;

Une fois le message in-app affiché, tout changement d’orientation de l’appareil pendant que le message est encore visible entraînera la rotation du message avec l’appareil (à condition que cette orientation soit prise en charge par la configuration orientation du message).

L’orientation de l’appareil doit également être prise en charge par la propriété orientation du message in-app pour que le message s’affiche. De plus, le paramètre preferredOrientation ne sera respecté que s’il est inclus dans les orientations d’interface prises en charge par votre application, dans la section Deployment Info des paramètres de votre cible dans Xcode.

Orientations prises en charge dans Xcode.

Personnaliser le moment d’affichage

Vous pouvez contrôler si un message in-app disponible s’affichera à certains moments de l’expérience utilisateur. Si, dans certaines situations, vous ne souhaitez pas que le message in-app apparaisse, par exemple pendant un jeu en plein écran ou sur un écran de chargement, vous pouvez retarder ou ignorer les messages in-app en attente. Pour contrôler le moment d’affichage des messages in-app, utilisez la méthode déléguée inAppMessage(_:displayChoiceForMessage:) pour définir la propriété BrazeInAppMessageUI.DisplayChoice.

func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  displayChoiceForMessage message: Braze.InAppMessage
) -> BrazeInAppMessageUI.DisplayChoice
- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui displayChoiceForMessage:(BRZInAppMessageRaw *)message

Configurez BrazeInAppMessageUI.DisplayChoice pour renvoyer l’une des valeurs suivantes :

Choix d’affichage Comportement
.now Le message sera affiché immédiatement. Il s’agit de la valeur par défaut.
.reenqueue Le message ne sera pas affiché et sera replacé en haut de la pile.
.later Le message ne sera pas affiché et sera replacé en haut de la pile. (Obsolète, veuillez utiliser .reenqueue)
.discard Le message sera ignoré et ne sera pas affiché.

Masquer la barre d’état

Pour les messages in-app Full, FullImage et HTML, le SDK masque la barre d’état par défaut. Pour les autres types de messages in-app, la barre d’état n’est pas modifiée. Pour configurer ce comportement, utilisez la méthode déléguée inAppMessage(_:prepareWith:) pour définir la propriété statusBarHideBehavior sur le PresentationContext. Ce champ accepte l’une des valeurs suivantes :

Comportement de masquage de la barre d’état Description
.auto La vue du message détermine l’état de masquage de la barre d’état.
.hidden Toujours masquer la barre d’état.
.visible Toujours afficher la barre d’état.

Désactiver le mode sombre

Pour empêcher les messages in-app d’adopter le style du mode sombre lorsque l’appareil de l’utilisateur a le mode sombre activé, implémentez la méthode déléguée inAppMessage(_:prepareWith:). Le PresentationContext transmis à la méthode contient une référence à l’objet InAppMessage à présenter. Chaque InAppMessage possède une propriété themes contenant un thème de mode dark et un thème de mode light. Si vous définissez la propriété themes.dark sur nil, Braze présentera automatiquement le message in-app en utilisant son thème clair.

Les types de messages in-app avec des boutons ont un objet themes supplémentaire dans leur propriété buttons. Pour empêcher les boutons d’adopter le style du mode sombre, vous pouvez utiliser map(_:) pour créer un nouveau tableau de boutons avec un thème light et sans thème dark.

func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  prepareWith context: inout BrazeInAppMessageUI.PresentationContext
) {
  switch context.message {
    case .slideup:
      guard var slideup = context.message.slideup else { return }
      slideup.themes.dark = nil
      context.message.slideup = slideup

    case .modal:
      guard var modal = context.message.modal else { return }
      modal.themes.dark = nil
      modal.buttons = modal.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.modal = modal

    case .modalImage:
      guard var modalImage = context.message.modalImage else { return }
      modalImage.themes.dark = nil
      modalImage.buttons = modalImage.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.modalImage = modalImage

    case .full:
      guard var full = context.message.full else { return }
      full.themes.dark = nil
      full.buttons = full.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.full = full

    case .fullImage:
      guard var fullImage = context.message.fullImage else { return }
      fullImage.themes.dark = nil
      fullImage.buttons = fullImage.buttons.map {
        var newButton = $0
        newButton.themes = .init(themes: ["light": $0.themes.light])
        return newButton
      }
      context.message.fullImage = fullImage

    default:
      break
  }
}
- (void)inAppMessage:(BrazeInAppMessageUI *)ui
         prepareWith:(BrazeInAppMessageUIPresentationContextRaw *)context {
  switch (context.message.type) {
    case BRZInAppMessageRawTypeSlideup: {
      NSMutableDictionary *updatedThemes = [context.message.themes mutableCopy];
      [updatedThemes removeObjectForKey:@"dark"];
      context.message.themes = updatedThemes;
      break;
    }
    case BRZInAppMessageRawTypeModal:
    case BRZInAppMessageRawTypeFull:
    {
      NSMutableDictionary *updatedThemes = [context.message.themes mutableCopy];
      [updatedThemes removeObjectForKey:@"dark"];
      context.message.themes = updatedThemes;

      NSMutableArray *updatedButtons = [NSMutableArray arrayWithCapacity:context.message.buttons.count];
      for (BRZInAppMessageRawButton *button in context.message.buttons) {
        BRZInAppMessageRawButtonTheme *lightTheme = BRZInAppMessageRawButtonTheme.defaultLight;
        BRZInAppMessageRawButton *newButton = [button mutableCopy];
        newButton.textColor = lightTheme.textColor;
        newButton.backgroundColor = lightTheme.backgroundColor;
        newButton.borderColor = lightTheme.borderColor;
        [updatedButtons addObject:newButton];
      }
      context.message.buttons = updatedButtons;
      break;
    }
    default:
      break;
  }
}

Personnaliser l’invite d’évaluation de l’App Store

Vous pouvez utiliser des messages in-app dans une campagne pour demander aux utilisateurs de laisser un avis sur l’App Store.

Étape 1 : Définir le délégué de message in-app

Tout d’abord, définissez le BrazeInAppMessageUIDelegate dans votre application.

Étape 2 : Désactiver le message d’évaluation par défaut de l’App Store

Ensuite, implémentez la méthode de délégation inAppMessage(_:displayChoiceForMessage:) pour désactiver le message d’évaluation par défaut de l’App Store.

func inAppMessage(_ ui: BrazeInAppMessageUI, displayChoiceForMessage message: Braze.InAppMessage) -> BrazeInAppMessageUI.DisplayChoice {
  if message.extras["AppStore Review"] != nil,
    let messageUrl = message.clickAction.url {
      UIApplication.shared.open(messageUrl, options: [:], completionHandler: nil)
      return .discard
  } else {
    return .now
  }
}
- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui
                            displayChoiceForMessage:(BRZInAppMessageRaw *)message {
  if (message.extras != nil && message.extras[@"AppStore Review"] != nil) {
    [[UIApplication sharedApplication] openURL:message.url options:@{} completionHandler:nil];
    return BRZInAppMessageUIDisplayChoiceDiscard;
  } else {
    return BRZInAppMessageUIDisplayChoiceNow;
  }
}

Dans votre gestionnaire scene:openURLContexts:, ajoutez le code suivant pour traiter le deep link {YOUR-APP-SCHEME}:app-store-review. Notez que vous devrez importer StoreKit pour utiliser SKStoreReviewController :

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
  guard let url = URLContexts.first?.url else { return }
  let urlString = url.absoluteString.removingPercentEncoding
  if (urlString == "{YOUR-APP-SCHEME}:app-store-review") {
    SKStoreReviewController.requestReview()
    return;
  }
  // Other deep link handling code…
}
- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
  NSURL *url = URLContexts.allObjects.firstObject.URL;
  NSString *urlString = url.absoluteString.stringByRemovingPercentEncoding;
  if ([urlString isEqualToString:@"{YOUR-APP-SCHEME}:app-store-review"]) {
    [SKStoreReviewController requestReview];
    return;
  }
  // Other deep link handling code…
}

Étape 4 : Définir un comportement de clic personnalisé

Ensuite, créez une campagne de communication par message in-app avec les éléments suivants :

  • La paire clé-valeur "AppStore Review" : "true"
  • Le comportement au clic défini sur « Deep link vers l’application », en utilisant le deep link {YOUR-APP-SCHEME}:app-store-review.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK React Native de Braze.

Méthodes d’enregistrement

Vous pouvez utiliser ces méthodes en passant votre instance BrazeInAppMessage pour enregistrer les analyses et effectuer des actions :

Méthode Description
logInAppMessageClicked(inAppMessage) Enregistre un clic pour les données du message in-app fourni.
logInAppMessageImpression(inAppMessage) Enregistre une impression pour les données du message in-app fourni.
logInAppMessageButtonClicked(inAppMessage, buttonId) Enregistre un clic sur un bouton pour les données du message in-app et l’ID du bouton fournis.
hideCurrentInAppMessage() Ferme le message in-app actuellement affiché.
performInAppMessageAction(inAppMessage) Exécute l’action associée à un message in-app.
performInAppMessageButtonAction(inAppMessage, buttonId) Exécute l’action associée à un bouton de message in-app.

Traitement des données de message

Dans la plupart des cas, vous pouvez utiliser la méthode Braze.addListener pour enregistrer des écouteurs d’événements afin de traiter les données provenant des messages in-app.

De plus, vous pouvez accéder aux données des messages in-app dans la couche JavaScript en appelant la méthode Braze.subscribeToInAppMessage pour que les SDK publient un événement inAppMessageReceived lorsqu’un message in-app est déclenché. Passez un rappel à cette méthode pour exécuter votre propre code lorsque le message in-app est déclenché et reçu par l’écouteur.

Pour personnaliser le traitement des données de message, consultez les exemples de déploiement suivants :

Pour améliorer le comportement par défaut, ou si vous n’avez pas accès au code natif iOS ou Android pour le personnaliser, nous vous recommandons de désactiver l’interface utilisateur par défaut tout en continuant à recevoir les événements de messages in-app de Braze. Pour désactiver l’interface utilisateur par défaut, passez false à la méthode Braze.subscribeToInAppMessage et utilisez les données du message in-app pour construire votre propre message en JavaScript. Notez que vous devrez enregistrer manuellement les analyses sur vos messages si vous choisissez de désactiver l’interface utilisateur par défaut.

import Braze from "@braze/react-native-sdk";

// Option 1: Listen for the event directly via `Braze.addListener`.
//
// You may use this method to accomplish the same thing if you don't
// wish to make any changes to the default Braze UI.
Braze.addListener(Braze.Events.IN_APP_MESSAGE_RECEIVED, (event) => {
  console.log(event.inAppMessage);
});

// Option 2: Call `subscribeToInAppMessage`.
//
// Pass in `false` to disable the automatic display of in-app messages.
Braze.subscribeToInAppMessage(false, (event) => {
  console.log(event.inAppMessage);
  // Use `event.inAppMessage` to construct your own custom message UI.
});

Pour inclure une logique plus avancée afin de déterminer s’il faut afficher ou non un message in-app à l’aide de l’interface utilisateur intégrée, implémentez les messages in-app via la couche native.

Implémentez le IInAppMessageManagerListener comme décrit dans notre article Android sur le Custom Manager Listener. Dans votre implémentation de beforeInAppMessageDisplayed, vous pouvez accéder aux données de inAppMessage, les envoyer à la couche JavaScript et décider d’afficher ou non le message natif en fonction de la valeur de retour.

Pour en savoir plus sur ces valeurs, consultez notre documentation Android.

// In-app messaging
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
    WritableMap parameters = new WritableNativeMap();
    parameters.putString("inAppMessage", inAppMessage.forJsonPut().toString());
    getReactNativeHost()
        .getReactInstanceManager()
        .getCurrentReactContext()
        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
        .emit("inAppMessageReceived", parameters);
    // Note: return InAppMessageOperation.DISCARD if you would like
    // to prevent the Braze SDK from displaying the message natively.
    return InAppMessageOperation.DISPLAY_NOW;
}

Surcharger le délégué d’interface utilisateur par défaut

Par défaut, BrazeInAppMessageUI est créé et assigné lorsque vous initialisez l’instance braze. BrazeInAppMessageUI est une implémentation du protocole BrazeInAppMessagePresenter et est fourni avec une propriété delegate qui peut être utilisée pour personnaliser le traitement des messages in-app reçus.

  1. Implémentez le délégué BrazeInAppMessageUIDelegate comme décrit dans notre tutoriel sur l’interface utilisateur des messages in-app iOS.

  2. Dans la méthode déléguée inAppMessage(_:displayChoiceForMessage:), vous pouvez accéder aux données de inAppMessage, les envoyer à la couche JavaScript et décider d’afficher ou non le message natif en fonction de la valeur de retour.

Pour plus de détails sur ces valeurs, consultez notre documentation iOS.

- (enum BRZInAppMessageUIDisplayChoice)inAppMessage:(BrazeInAppMessageUI *)ui
                            displayChoiceForMessage:(BRZInAppMessageRaw *)message {
  // Convert the message to a JavaScript representation.
  NSData *inAppMessageData = [message json];
  NSString *inAppMessageString = [[NSString alloc] initWithData:inAppMessageData encoding:NSUTF8StringEncoding];
  NSDictionary *arguments = @{
    @"inAppMessage" : inAppMessageString
  };

  // Send to JavaScript.
  [self sendEventWithName:@"inAppMessageReceived" body:arguments];

  // Note: Return `BRZInAppMessageUIDisplayChoiceDiscard` if you would like
  // to prevent the Braze SDK from displaying the message natively.
  return BRZInAppMessageUIDisplayChoiceNow;
}

Pour utiliser ce délégué, assignez-le à brazeInAppMessagePresenter.delegate après avoir initialisé l’instance braze.

@import BrazeUI;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:apiKey endpoint:endpoint];
  Braze *braze = [BrazeReactBridge initBraze:configuration];
  ((BrazeInAppMessageUI *)braze.inAppMessagePresenter).delegate = [[CustomDelegate alloc] init];
  AppDelegate.braze = braze;
}

Surcharger l’interface utilisateur native par défaut

Si vous souhaitez personnaliser entièrement la présentation de vos messages in-app au niveau de la couche native iOS, conformez-vous au protocole BrazeInAppMessagePresenter et assignez votre présenteur personnalisé en suivant cet exemple :

BRZConfiguration *configuration = [[BRZConfiguration alloc] initWithApiKey:apiKey endpoint:endpoint];
Braze *braze = [BrazeReactBridge initBraze:configuration];
braze.inAppMessagePresenter = [[MyCustomPresenter alloc] init];
AppDelegate.braze = braze;

Personnaliser le comportement d’affichage

Vous pouvez modifier le comportement d’affichage des messages in-app au moment de l’exécution via les méthodes suivantes :

// Sets in-app messages to display immediately when triggered.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISPLAY_NOW);

// Sets in-app messages to display at a later time and be saved in a stack.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISPLAY_LATER);

// Sets in-app messages to be discarded after being triggered.
Appboy.AppboyBinding.SetInAppMessageDisplayAction(BrazeUnityInAppMessageDisplayActionType.IAM_DISCARD);

Définir un listener personnalisé

Si vous avez besoin de plus de contrôle sur la façon dont un utilisateur interagit avec les messages in-app, utilisez un BrazeInAppMessageListener et assignez-le à Appboy.AppboyBinding.inAppMessageListener. Pour les délégués que vous ne souhaitez pas utiliser, vous pouvez simplement les laisser à null.

BrazeInAppMessageListener listener = new BrazeInAppMessageListener() {
  BeforeInAppMessageDisplayed = BeforeInAppMessageDisplayed,
  OnInAppMessageButtonClicked = OnInAppMessageButtonClicked,
  OnInAppMessageClicked       = OnInAppMessageClicked,
  OnInAppMessageHTMLClicked   = OnInAppMessageHTMLClicked,
  OnInAppMessageDismissed     = OnInAppMessageDismissed,
};
Appboy.AppboyBinding.inAppMessageListener = listener;

public void BeforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  // Executed before an in-app message is displayed.
}

public void OnInAppMessageButtonClicked(IInAppMessage inAppMessage, InAppMessageButton inAppMessageButton) {
  // Executed whenever an in-app message button is clicked.
}

public void OnInAppMessageClicked(IInAppMessage inAppMessage) {
  // Executed whenever an in-app message is clicked.
}

public void OnInAppMessageHTMLClicked(IInAppMessage inAppMessage, Uri uri) {
  // Executed whenever an HTML in-app message is clicked.
}

public void OnInAppMessageDismissed(IInAppMessage inAppMessage) {
  // Executed whenever an in-app message is dismissed without a click.
}
New Stuff!