Ir al contenido

Personalizar mensajes dentro de la aplicación

Aprende a personalizar los mensajes dentro de la aplicación para el SDK de Braze. Para conocer técnicas de estilo avanzadas, consulta nuestro tutorial sobre cómo personalizar el estilo de los mensajes mediante pares clave-valor.

Requisitos previos

Antes de poder utilizar esta característica, tendrás que integrar el SDK Web de Braze.

Estilos personalizados

Los elementos de la interfaz de usuario de Braze vienen con un aspecto predeterminado que crea una experiencia de mensajería dentro de la aplicación neutral y busca la coherencia con otras plataformas móviles de Braze. Los estilos predeterminados de Braze se definen en CSS dentro del SDK de Braze.

Configuración de un estilo predeterminado

Al anular los estilos seleccionados en tu aplicación, puedes personalizar nuestros tipos de mensajes dentro de la aplicación estándar con tus propias imágenes de fondo, familias de fuentes, estilos, tamaños, animaciones y mucho más.

Por ejemplo, lo siguiente es un ejemplo de modificación que hará que los encabezados de un mensaje dentro de la aplicación aparezcan en cursiva:

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

Consulta los JSDocs para más información.

Personalizar el índice z

De manera predeterminada, los mensajes dentro de la aplicación se muestran utilizando z-index: 9001. Esto es configurable mediante la opción de inicialización inAppMessageZIndex en el caso de que tu sitio web estilice elementos con valores superiores a ese.

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

Personalizar el descarte de mensajes

De forma predeterminada, cuando se muestra un mensaje dentro de la aplicación, al pulsar el botón de escape o hacer clic en el fondo gris de la página se descartará el mensaje. Configura la opción de inicialización requireExplicitInAppMessageDismissal en true para evitar este comportamiento y requerir un clic explícito en el botón para descartar los mensajes.

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

Personalizar el momento de visualización

Para anular el momento de visualización predeterminado, elimina las llamadas a braze.automaticallyShowInAppMessages() y gestiona los mensajes en braze.subscribeToInAppMessage(). Registra tu devolución de llamada antes de braze.openSession(), para poder interceptar los mensajes de inicio de sesión y decidir si mostrar o aplazar cada mensaje.

De forma predeterminada, Braze muestra los mensajes dentro de la aplicación cuando se desencadenan y son elegibles para mostrarse. Si necesitas un comportamiento diferente para tu experiencia de la aplicación, utiliza una devolución de llamada personalizada para aplazar o mostrar mensajes según tu propia lógica.

El siguiente ejemplo muestra cómo suscribirse a mensajes dentro de la aplicación desencadenados, aplazar mensajes seleccionados y mostrar mensajes aplazados más tarde:

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);
}

Para obtener orientación relacionada sobre la personalización de la entrega, consulta:

Para configurar tus enlaces de mensajes dentro de la aplicación para que se abran en una pestaña nueva, configura la opción openInAppMessagesInNewTab en true para forzar que todos los enlaces de los clics de mensajes dentro de la aplicación se abran en una pestaña o ventana nueva.

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

Requisitos previos

Antes de poder utilizar esta característica, tendrás que integrar el SDK de Braze para Android. También tendrás que configurar los mensajes dentro de la aplicación.

Configurar listeners personalizados del administrador

Aunque el listener de BrazeInAppMessageManager puede gestionar automáticamente la visualización y el ciclo de vida de los mensajes dentro de la aplicación, necesitarás implementar un listener personalizado del administrador si deseas personalizar por completo tus mensajes.

El SDK de Braze tiene una clase predeterminada DefaultHtmlInAppMessageActionListener que se utiliza si no se define un listener personalizado y que realiza la acción apropiada automáticamente. Si necesitas más control sobre cómo un usuario interactúa con los diferentes botones dentro de un mensaje HTML personalizado dentro de la aplicación, implementa una clase personalizada IHtmlInAppMessageActionListener.

Este listener se aplica tanto a los mensajes creados con HTML personalizado como a los mensajes creados con el editor de arrastrar y soltar (DnD). No se aplica a los IAM tradicionales. Los IAM tradicionales son los tipos de mensajes integrados de Braze, renderizados por el SDK (por ejemplo, deslizamiento hacia arriba, modal y completo) creados en el creador de mensajes dentro de la aplicación original utilizando diseños predefinidos. A diferencia de los IAM de HTML personalizado y DnD, no pasan por el flujo del listener de acciones HTML.

Si configuras un IHtmlInAppMessageActionListener personalizado, su lógica anulará el comportamiento de clic predeterminado para todos los mensajes DnD. Asegúrate de que tu equipo de marketing esté al tanto de esto, ya que puede afectar sus Campaigns de maneras inesperadas.

Paso 1: Implementar el listener personalizado del administrador

Paso 1.1: Implementar IInAppMessageManagerListener

Crea una clase que implemente IInAppMessageManagerListener.

Las devoluciones de llamada en tu IInAppMessageManagerListener también se invocarán en varios puntos del ciclo de vida del mensaje dentro de la aplicación. Por ejemplo, si configuras un listener personalizado del administrador cuando se recibe un mensaje dentro de la aplicación de Braze, se llamará al método beforeInAppMessageDisplayed(). Si tu implementación de este método devuelve InAppMessageOperation.DISCARD, eso indica a Braze que el mensaje dentro de la aplicación será gestionado por la aplicación anfitriona y no debe ser mostrado por Braze. Si se devuelve InAppMessageOperation.DISPLAY_NOW, Braze intentará mostrar el mensaje dentro de la aplicación. Este método debe usarse si decides mostrar el mensaje dentro de la aplicación de una manera personalizada.

IInAppMessageManagerListener también incluye métodos delegados para clics en mensajes y botones, que pueden usarse en casos como interceptar un mensaje cuando se hace clic en un botón o mensaje para procesamiento adicional.

Paso 1.2: Vincular métodos del ciclo de vida de la vista de IAM (opcional)

La interfaz IInAppMessageManagerListener tiene métodos de vista de mensajes dentro de la aplicación que se invocan en puntos distintos del ciclo de vida de la vista del mensaje dentro de la aplicación. Estos métodos se invocan en el siguiente orden:

  1. beforeInAppMessageViewOpened: Se invoca justo antes de que el mensaje dentro de la aplicación se agregue a la vista de la actividad. El mensaje dentro de la aplicación aún no es visible para el usuario en este momento.
  2. afterInAppMessageViewOpened: Se invoca justo después de que el mensaje dentro de la aplicación se agrega a la vista de la actividad. El mensaje dentro de la aplicación ahora es visible para el usuario en este momento.
  3. beforeInAppMessageViewClosed: Se invoca justo antes de que el mensaje dentro de la aplicación se elimine de la vista de la actividad. El mensaje dentro de la aplicación aún es visible para el usuario en este momento.
  4. afterInAppMessageViewClosed: Se invoca justo después de que el mensaje dentro de la aplicación se elimina de la vista de la actividad. El mensaje dentro de la aplicación ya no es visible para el usuario en este momento.

Ten en cuenta que el tiempo entre afterInAppMessageViewOpened y beforeInAppMessageViewClosed es cuando la vista del mensaje dentro de la aplicación está en pantalla, visible para el usuario.

Crea una clase que implemente IHtmlInAppMessageActionListener.

Las devoluciones de llamada en tu IHtmlInAppMessageActionListener se invocarán siempre que el usuario inicie cualquiera de las siguientes acciones dentro del mensaje HTML dentro de la aplicación:

  • Hace clic en el botón de cerrar
  • Dispara un evento personalizado
  • Hace clic en una URL dentro del mensaje HTML dentro de la aplicación
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
    }
}

Paso 2: Instruir a Braze para que use el listener personalizado del administrador

Después de crear tu IInAppMessageManagerListener, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener() para instruir a BrazeInAppMessageManager a que use tu IInAppMessageManagerListener personalizado en lugar del listener predeterminado. Haz esto en tu Application.onCreate() antes de cualquier otra llamada a Braze, para que el listener personalizado se configure antes de que se muestre cualquier mensaje dentro de la aplicación.

Modificar mensajes dentro de la aplicación antes de mostrarlos

Cuando se recibe un nuevo mensaje dentro de la aplicación y ya hay uno mostrándose, el nuevo mensaje se colocará en la parte superior de la pila y podrá mostrarse más adelante.

Sin embargo, si no hay ningún mensaje dentro de la aplicación mostrándose, se llamará al siguiente método delegado en IInAppMessageManagerListener:

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

El valor de retorno de InAppMessageOperation() puede controlar cuándo debe mostrarse el mensaje. El uso sugerido de este método sería retrasar los mensajes en ciertas partes de la aplicación devolviendo DISPLAY_LATER cuando los mensajes dentro de la aplicación distraerían la experiencia de la aplicación del usuario.

Valor de retorno de InAppMessageOperation Comportamiento
DISPLAY_NOW Se mostrará el mensaje
DISPLAY_LATER El mensaje se devolverá a la pila y se mostrará en la próxima oportunidad disponible
DISCARD El mensaje se descartará
null El mensaje se ignorará. Este método NO debe devolver null

Consulta InAppMessageOperation para obtener más detalles.

En Android, esto se hace llamando a logClick y logImpression en los mensajes dentro de la aplicación y logButtonClick en los mensajes dentro de la aplicación inmersivos.

Después de crear tu IHtmlInAppMessageActionListener, llama a BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener() para instruir a BrazeInAppMessageManager a que use tu IHtmlInAppMessageActionListener personalizado en lugar del listener de acción predeterminado.

Te recomendamos configurar tu IHtmlInAppMessageActionListener en tu Application.onCreate() antes de cualquier otra llamada a Braze. Esto configurará el listener de acción personalizado antes de que se muestre cualquier mensaje dentro de la aplicación:

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

Configurar fábricas personalizadas

Puedes anular varios valores predeterminados a través de objetos de fábrica personalizados. Estos pueden registrarse con el SDK de Braze según sea necesario para lograr los resultados deseados. Sin embargo, si decides anular una fábrica, probablemente necesites delegar explícitamente en la predeterminada o reimplementar la funcionalidad proporcionada por la fábrica predeterminada de Braze. El siguiente fragmento de código ilustra cómo proporcionar implementaciones personalizadas de las interfaces IInAppMessageViewFactory e IInAppMessageViewWrapperFactory.

Tipos de mensajes dentro de la aplicación

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

Tipos de mensajes dentro de la aplicación

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());
  }
}

Los tipos de mensajes dentro de la aplicación de Braze son lo suficientemente versátiles como para cubrir la mayoría de los casos de uso personalizados. Sin embargo, si deseas definir completamente la apariencia visual de tus mensajes dentro de la aplicación en lugar de usar un tipo predeterminado, Braze lo hace posible configurando una fábrica de vistas personalizada.

El BrazeInAppMessageManager gestiona automáticamente la colocación del modelo de mensaje dentro de la aplicación en la jerarquía de vistas de la actividad existente de forma predeterminada usando DefaultInAppMessageViewWrapper. Si necesitas personalizar cómo se colocan los mensajes dentro de la aplicación en la jerarquía de vistas, debes usar un IInAppMessageViewWrapperFactory personalizado.

Los mensajes dentro de la aplicación tienen un comportamiento de animación predefinido. Los mensajes de tipo Slideup se deslizan hacia la pantalla; los mensajes full y modal aparecen y desaparecen con efecto de fundido. Si deseas definir comportamientos de animación personalizados para tus mensajes dentro de la aplicación, Braze lo hace posible configurando una fábrica de animación personalizada.

Paso 1: Implementar la fábrica

Crea una clase que implemente 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)
      }
    }
  }
}

Crea una clase que implemente IInAppMessageViewWrapperFactory y devuelva un IInAppMessageViewWrapper.

Esta fábrica se llama inmediatamente después de crear la vista del mensaje dentro de la aplicación. La forma más sencilla de implementar un IInAppMessageViewWrapper personalizado es simplemente extender el DefaultInAppMessageViewWrapper predeterminado:

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()
  }
}

Crea una clase que implemente 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
  }
}

Paso 2: Indicar a Braze que use la fábrica

Después de crear tu IInAppMessageViewFactory, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory() para indicar a BrazeInAppMessageManager que use tu IInAppMessageViewFactory personalizada en lugar de la fábrica de vistas predeterminada.

Cómo funciona

La vista de mensaje dentro de la aplicación de tipo slideup implementa IInAppMessageView. Las vistas de mensajes de tipo full y modal implementan IInAppMessageImmersiveView. Implementar una de estas clases permite a Braze agregar listeners de clic a tu vista personalizada donde sea apropiado. Todas las clases de vista de Braze extienden la clase View de Android.

Implementar IInAppMessageView te permite definir una parte determinada de tu vista personalizada como clicable. Implementar IInAppMessageImmersiveView te permite definir vistas de botones de mensaje y una vista de botón de cierre.

Después de crear tu IInAppMessageViewWrapper, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory() para indicar a BrazeInAppMessageManager que use tu IInAppMessageViewWrapperFactory personalizada en lugar de la fábrica de envoltorio de vista predeterminada.

Te recomendamos configurar tu IInAppMessageViewWrapperFactory en tu Application.onCreate() antes de cualquier otra llamada a Braze. Esto establecerá la fábrica de envoltorio de vista personalizada antes de que se muestre cualquier mensaje dentro de la aplicación:

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

Una vez creada tu IInAppMessageAnimationFactory, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory() para indicar a BrazeInAppMessageManager que use tu IInAppMessageAnimationFactory personalizada en lugar de la fábrica de animación predeterminada.

Te recomendamos configurar tu IInAppMessageAnimationFactory en tu Application.onCreate() antes de cualquier otra llamada a Braze. Esto establecerá la fábrica de animación personalizada antes de que se muestre cualquier mensaje dentro de la aplicación.

Estilos personalizados

Los elementos de la interfaz de usuario de Braze vienen con una apariencia predeterminada que coincide con las directrices estándar de la interfaz de usuario de Android y proporciona una experiencia fluida. Este artículo de referencia cubre la personalización de estilos de mensajes dentro de la aplicación para tu aplicación Android o FireOS.

Configurar un estilo predeterminado

Puedes ver los estilos predeterminados en el archivo styles.xml del 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 lo prefieres, puedes sobrescribir estos estilos para crear una apariencia que se adapte mejor a tu aplicación.

Para sobrescribir un estilo, cópialo en su totalidad en el archivo styles.xml de tu proyecto y haz las modificaciones necesarias. El estilo completo debe copiarse en tu archivo local styles.xml para que todos los atributos se configuren correctamente. Ten en cuenta que estos estilos personalizados son para cambios en elementos individuales de la interfaz de usuario, no cambios generales en los diseños. Los cambios a nivel de diseño deben gestionarse con vistas personalizadas.

Personalizar la fuente

Puedes configurar una fuente personalizada localizando el tipo de letra en el directorio res/font. Para usarla, sobrescribe el estilo del texto del mensaje, los encabezados y el texto de los botones, y usa el atributo fontFamily para indicar a Braze que utilice tu familia de fuentes personalizada.

Por ejemplo, para actualizar la fuente del texto de los botones de tu mensaje dentro de la aplicación, sobrescribe el estilo Braze.InAppMessage.Button y haz referencia a tu familia de fuentes personalizada. El valor del atributo debe apuntar a una familia de fuentes en tu directorio res/font.

Este es un ejemplo abreviado con una familia de fuentes personalizada, my_custom_font_family, referenciada en la última línea:

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

Aparte del estilo Braze.InAppMessage.Button para el texto de los botones, el estilo para el texto del mensaje es Braze.InAppMessage.Message y el estilo para los encabezados del mensaje es Braze.InAppMessage.Header. Si quieres usar tu familia de fuentes personalizada en todo el texto posible de los mensajes dentro de la aplicación, puedes configurar tu familia de fuentes en el estilo Braze.InAppMessage, que es el estilo padre de todos los mensajes dentro de la aplicación.

Descartar mensajes

Deslizar para descartar mensajes de deslizamiento hacia arriba

De forma predeterminada, los mensajes dentro de la aplicación de deslizamiento hacia arriba se pueden descartar con un gesto de deslizamiento. La dirección del deslizamiento depende de la posición del mensaje:

  • Deslizamiento a la izquierda o derecha: Descarta el deslizamiento hacia arriba independientemente de su posición.
  • Deslizamiento hacia arriba desde abajo: Deslizar de arriba hacia abajo descarta el mensaje. Deslizar de abajo hacia arriba no lo descarta.
  • Deslizamiento hacia arriba desde arriba: Deslizar de abajo hacia arriba descarta el mensaje. Deslizar de arriba hacia abajo no lo descarta.

Este comportamiento de deslizamiento está integrado en el DefaultInAppMessageViewWrapper predeterminado y se aplica únicamente a los mensajes dentro de la aplicación de deslizamiento hacia arriba. Los mensajes dentro de la aplicación modales y de pantalla completa no admiten la función de deslizar para descartar. Para personalizar este comportamiento, puedes implementar una fábrica de envoltorio de vista personalizada.

Desactivar el descarte con el botón de retroceso

De forma predeterminada, el botón de retroceso del hardware descarta los mensajes dentro de la aplicación de Braze. Este comportamiento se puede desactivar mensaje por mensaje mediante BrazeInAppMessageManager.setBackButtonDismissesInAppMessageView().

En el siguiente ejemplo, disable_back_button es un par clave-valor personalizado configurado en el mensaje dentro de la aplicación que indica si el mensaje debe permitir que el botón de retroceso lo descarte:

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

Habilitar el descarte al tocar fuera

De forma predeterminada, descartar el modal al tocar fuera está configurado como false. Establecer este valor en true hará que el mensaje dentro de la aplicación modal se descarte cuando el usuario toque fuera del mensaje dentro de la aplicación. Este comportamiento se puede alternar llamando a:

BrazeInAppMessageManager.getInstance().setClickOutsideModalViewDismissInAppMessageView(true)

Personalizar la orientación

Para establecer una orientación fija para un mensaje dentro de la aplicación, primero configura un receptor personalizado del administrador de mensajes dentro de la aplicación. Después, actualiza la orientación en el objeto IInAppMessage en el método delegado 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
}

Para dispositivos tipo tableta, los mensajes dentro de la aplicación aparecerán en el estilo de orientación preferido del usuario, independientemente de la orientación real de la pantalla.

Desactivar el tema oscuro

De forma predeterminada, beforeInAppMessageDisplayed() de IInAppMessageManagerListener comprueba la configuración del sistema y habilita de forma condicional el estilo del tema oscuro en el mensaje con el siguiente código:

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

Para cambiar esto, puedes llamar a enableDarkTheme en cualquier paso del proceso previo a la visualización para implementar tu propia lógica condicional.

Personalizar la solicitud de reseña de Google Play

Debido a las limitaciones y restricciones establecidas por Google, las solicitudes personalizadas de reseña de Google Play no son compatibles actualmente con Braze. Aunque algunos usuarios han podido integrar estas solicitudes con éxito, otros han mostrado tasas de éxito bajas debido a las cuotas de Google Play. Integra bajo tu propia responsabilidad. Consulta la documentación sobre solicitudes de reseña dentro de la aplicación de Google Play.

Requisitos previos

Antes de poder utilizar esta característica, tendrás que integrar el SDK Swift de Braze.

Configurar el delegado de UI (obligatorio)

Para personalizar la presentación de los mensajes dentro de la aplicación y reaccionar a diversos eventos del ciclo de vida, necesitarás configurar BrazeInAppMessageUIDelegate. Se trata de un protocolo de delegado utilizado para recibir y procesar las cargas útiles de mensajes dentro de la aplicación desencadenados, recibir eventos del ciclo de vida de visualización y controlar el tiempo de visualización. Para utilizar BrazeInAppMessageUIDelegate, debes:

  • Usar la implementación predeterminada de BrazeInAppMessageUI como tu inAppMessagePresenter.
  • Incluir la biblioteca BrazeUI en tu proyecto.

Paso 1: Implementar el protocolo BrazeInAppMessageUIDelegate

Primero, implementa el protocolo BrazeInAppMessageUIDelegate y cualquier método correspondiente que desees. En el siguiente ejemplo, este protocolo se implementa en la clase AppDelegate de la aplicación.

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

@end

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

Paso 2: Asignar el objeto delegate

Asigna el objeto delegate en la instancia de BrazeInAppMessageUI antes de asignar esta interfaz de usuario de mensajes dentro de la aplicación como tu inAppMessagePresenter.

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

Comportamiento al hacer clic

Cada objeto Braze.InAppMessage contiene un ClickAction correspondiente, que define el comportamiento al hacer clic.

Tipos de acción de clic

La propiedad clickAction de tu Braze.InAppMessage tiene como valor predeterminado .none, pero se puede establecer con uno de los siguientes valores:

ClickAction Comportamiento al hacer clic
.url(URL, useWebView: Bool) Abre la URL proporcionada en un navegador externo. Si useWebView se establece en true, se abrirá en una vista web.
.none El mensaje se descartará al hacer clic.

Personalizar el comportamiento al hacer clic

Para personalizar este comportamiento, puedes modificar la propiedad clickAction consultando el siguiente ejemplo:

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

El método inAppMessage(_:prepareWith:) no está disponible en Objective-C.

Gestionar el comportamiento personalizado

El siguiente método delegado BrazeInAppMessageUIDelegate se llama cuando un usuario hace clic en un mensaje dentro de la aplicación. Esta devolución de llamada se activa para los clics iniciados por el usuario en los botones de mensajes dentro de la aplicación y en los botones de mensajes dentro de la aplicación HTML (enlaces), y se proporciona un ID de botón como parámetro opcional para estas interacciones. Esta devolución de llamada no se invoca para los clics programáticos activados a través de 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;

Este método devuelve un valor booleano para indicar si Braze debe continuar ejecutando la acción de 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;
}

Deslizar para cerrar mensajes de deslizamiento hacia arriba

De forma predeterminada, los mensajes dentro de la aplicación de deslizamiento hacia arriba se pueden cerrar con un gesto de deslizar. La dirección del deslizamiento depende de la posición del deslizamiento hacia arriba:

  • Deslizar a la izquierda o a la derecha: cierra el deslizamiento hacia arriba independientemente de su posición.
  • Deslizamiento hacia arriba desde abajo: deslizar de arriba hacia abajo cierra el mensaje. Deslizar de abajo hacia arriba no lo cierra.
  • Deslizamiento hacia arriba desde arriba: deslizar de abajo hacia arriba cierra el mensaje. Deslizar de arriba hacia abajo no lo cierra.

Este comportamiento de deslizar está integrado en el SlideupView predeterminado de BrazeInAppMessageUI y solo se aplica a los mensajes dentro de la aplicación de deslizamiento hacia arriba. Los mensajes dentro de la aplicación modales y de pantalla completa no son compatibles con el deslizar para cerrar. Para personalizar aún más la vista de deslizamiento hacia arriba, incluido el comportamiento de deslizar, puedes modificar los SlideupView.Attributes o proporcionar una vista personalizada mediante subclases.

Personalizar el cierre de modales

Para habilitar el cierre al tocar fuera del modal, puedes modificar la propiedad dismissOnBackgroundTap en la estructura Attributes del tipo de mensaje dentro de la aplicación que desees personalizar.

Por ejemplo, si deseas habilitar esta característica para los mensajes modales de imagen dentro de la aplicación, puedes configurar lo siguiente:

BrazeInAppMessageUI.ModalImageView.Attributes.defaults.dismissOnBackgroundTap = true

La personalización mediante Attributes no está disponible en Objective-C.

El valor predeterminado es false. Esto determina si el mensaje modal dentro de la aplicación se cerrará cuando el usuario toque fuera del mensaje dentro de la aplicación.

DismissModalOnOutsideTap Descripción
true Los mensajes modales dentro de la aplicación se cerrarán al tocar fuera.
false Predeterminado, los mensajes modales dentro de la aplicación no se cerrarán al tocar fuera.

Para más detalles sobre la personalización de mensajes dentro de la aplicación, consulta este artículo.

Personalizar la orientación del mensaje

Puedes personalizar la orientación de tus mensajes dentro de la aplicación. Puedes establecer una nueva orientación predeterminada para todos los mensajes o definir una orientación personalizada para un solo mensaje.

Para elegir una orientación predeterminada para todos los mensajes dentro de la aplicación, utiliza el método inAppMessage(_:prepareWith:) para establecer la propiedad preferredOrientation en el PresentationContext.

Por ejemplo, para establecer vertical como la orientación predeterminada:

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

Para establecer la orientación de un solo mensaje, modifica la propiedad 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;

Después de que se muestre el mensaje dentro de la aplicación, cualquier cambio de orientación del dispositivo mientras el mensaje sigue mostrándose hará que el mensaje rote con el dispositivo (siempre y cuando sea compatible con la configuración de orientation del mensaje).

La orientación del dispositivo también debe ser compatible con la propiedad orientation del mensaje dentro de la aplicación para que el mensaje se muestre. Además, la configuración de preferredOrientation solo se respetará si está incluida en las orientaciones de interfaz compatibles de tu aplicación, en la sección Deployment Info de la configuración de tu destino en Xcode.

Orientaciones compatibles en Xcode.

Personalizar el tiempo de visualización

Puedes controlar si un mensaje dentro de la aplicación disponible se mostrará durante ciertos puntos de la experiencia de tu usuario. Si hay situaciones en las que no deseas que aparezca el mensaje dentro de la aplicación, como durante un juego a pantalla completa o en una pantalla de carga, puedes retrasar o descartar los mensajes dentro de la aplicación pendientes. Para controlar el tiempo de los mensajes dentro de la aplicación, utiliza el método delegado inAppMessage(_:displayChoiceForMessage:) para establecer la propiedad BrazeInAppMessageUI.DisplayChoice.

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

Configura BrazeInAppMessageUI.DisplayChoice para devolver uno de los siguientes valores:

Opción de visualización Comportamiento
.now El mensaje se mostrará inmediatamente. Este es el valor predeterminado.
.reenqueue El mensaje no se mostrará y se colocará de nuevo en la parte superior de la pila.
.later El mensaje no se mostrará y se colocará de nuevo en la parte superior de la pila. (Obsoleto, utiliza .reenqueue en su lugar)
.discard El mensaje se descartará y no se mostrará.

Ocultar la barra de estado

Para los mensajes dentro de la aplicación Full, FullImage y HTML, el SDK oculta la barra de estado de forma predeterminada. Para otros tipos de mensajes dentro de la aplicación, la barra de estado no se modifica. Para configurar este comportamiento, utiliza el método delegado inAppMessage(_:prepareWith:) para establecer la propiedad statusBarHideBehavior en el PresentationContext. Este campo acepta uno de los siguientes valores:

Comportamiento de ocultación de la barra de estado Descripción
.auto La vista del mensaje decide el estado oculto de la barra de estado.
.hidden Ocultar siempre la barra de estado.
.visible Mostrar siempre la barra de estado.

Desactivar el modo oscuro

Para evitar que los mensajes dentro de la aplicación adopten el estilo del modo oscuro cuando el dispositivo del usuario tiene el modo oscuro habilitado, implementa el método delegado inAppMessage(_:prepareWith:). El PresentationContext que se pasa al método contiene una referencia al objeto InAppMessage que se va a presentar. Cada InAppMessage tiene una propiedad themes que contiene un tema de modo dark y otro light. Si estableces la propiedad themes.dark en nil, Braze presentará automáticamente el mensaje dentro de la aplicación utilizando su tema claro.

Los tipos de mensajes dentro de la aplicación con botones tienen un objeto themes adicional en su propiedad buttons. Para evitar que los botones adopten el estilo del modo oscuro, puedes usar map(_:) para crear un nuevo arreglo de botones con un tema light y sin tema 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;
  }
}

Personalizar la solicitud de reseña en la tienda de aplicaciones

Puedes usar mensajes dentro de la aplicación en una Campaign para pedir a los usuarios una reseña en la App Store.

Paso 1: Configurar el delegado de mensajes dentro de la aplicación

Primero, configura el BrazeInAppMessageUIDelegate en tu aplicación.

Paso 2: Desactivar el mensaje predeterminado de reseña de la App Store

A continuación, implementa el método delegado inAppMessage(_:displayChoiceForMessage:) para desactivar el mensaje predeterminado de reseña de la 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;
  }
}

En tu controlador scene:openURLContexts:, agrega el siguiente código para procesar el vínculo profundo {YOUR-APP-SCHEME}:app-store-review. Ten en cuenta que necesitarás importar StoreKit para usar 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…
}

Paso 4: Configurar un comportamiento de clic personalizado

A continuación, crea una Campaign de mensajería dentro de la aplicación con lo siguiente:

  • El par clave-valor "AppStore Review" : "true"
  • El comportamiento de clic configurado como “Deep Link Into App”, usando el vínculo profundo {YOUR-APP-SCHEME}:app-store-review.

Requisitos previos

Antes de poder utilizar esta característica, tendrás que integrar el SDK de React Native de Braze.

Métodos para registro

Puedes usar estos métodos pasando tu instancia de BrazeInAppMessage para registrar análisis y realizar acciones:

Método Descripción
logInAppMessageClicked(inAppMessage) Registra un clic para los datos del mensaje dentro de la aplicación proporcionado.
logInAppMessageImpression(inAppMessage) Registra una impresión para los datos del mensaje dentro de la aplicación proporcionado.
logInAppMessageButtonClicked(inAppMessage, buttonId) Registra un clic de botón para los datos del mensaje dentro de la aplicación y el ID de botón proporcionados.
hideCurrentInAppMessage() Descarta el mensaje dentro de la aplicación que se muestra actualmente.
performInAppMessageAction(inAppMessage) Ejecuta la acción de un mensaje dentro de la aplicación.
performInAppMessageButtonAction(inAppMessage, buttonId) Ejecuta la acción de un botón de mensaje dentro de la aplicación.

Gestión de datos de mensajes

En la mayoría de los casos, puedes utilizar el método Braze.addListener para registrar escuchas de eventos que gestionen los datos procedentes de los mensajes dentro de la aplicación.

Además, puedes acceder a los datos de los mensajes dentro de la aplicación en la capa JavaScript llamando al método Braze.subscribeToInAppMessage para que los SDK publiquen un evento inAppMessageReceived cuando se desencadene un mensaje dentro de la aplicación. Pasa una devolución de llamada a este método para ejecutar tu propio código cuando el mensaje dentro de la aplicación se desencadene y sea recibido por la escucha.

Para personalizar la forma en que se gestionan los datos de los mensajes, consulta los siguientes ejemplos de implementación:

Para mejorar el comportamiento predeterminado, o si no tienes acceso para personalizar el código nativo de iOS o Android, te recomendamos que desactives la interfaz de usuario predeterminada y sigas recibiendo eventos de mensajes dentro de la aplicación de Braze. Para desactivar la interfaz de usuario predeterminada, pasa false al método Braze.subscribeToInAppMessage y utiliza los datos del mensaje dentro de la aplicación para construir tu propio mensaje en JavaScript. Ten en cuenta que tendrás que registrar manualmente los análisis de tus mensajes si decides desactivar la interfaz de usuario predeterminada.

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.
});

Para incluir una lógica más avanzada que determine si mostrar o no un mensaje dentro de la aplicación utilizando la interfaz de usuario integrada, implementa los mensajes dentro de la aplicación a través de la capa nativa.

Implementa IInAppMessageManagerListener como se describe en nuestro artículo de Android sobre Custom Manager Listener. En tu implementación de beforeInAppMessageDisplayed, puedes acceder a los datos de inAppMessage, enviarlos a la capa JavaScript y decidir si mostrar o no el mensaje nativo basándote en el valor de retorno.

Para más información sobre estos valores, consulta nuestra documentación de 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;
}

Anulación del delegado de interfaz de usuario predeterminado

De forma predeterminada, BrazeInAppMessageUI se crea y se asigna cuando inicializas la instancia de braze. BrazeInAppMessageUI es una implementación del protocolo BrazeInAppMessagePresenter y viene con una propiedad delegate que puede utilizarse para personalizar la gestión de los mensajes dentro de la aplicación que se han recibido.

  1. Implementa el delegado BrazeInAppMessageUIDelegate como se describe en nuestro tutorial de interfaz de usuario de mensajes dentro de la aplicación de iOS.

  2. En el método delegado inAppMessage(_:displayChoiceForMessage:), puedes acceder a los datos de inAppMessage, enviarlos a la capa JavaScript y decidir si mostrar o no el mensaje nativo basándote en el valor de retorno.

Para más detalles sobre estos valores, consulta nuestra documentación de 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;
}

Para utilizar este delegado, asígnalo a brazeInAppMessagePresenter.delegate después de inicializar la instancia de 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;
}

Anulación de la interfaz de usuario nativa predeterminada

Si deseas personalizar completamente la presentación de tus mensajes dentro de la aplicación en la capa nativa de iOS, cumple con el protocolo BrazeInAppMessagePresenter y asigna tu presentador personalizado siguiendo este ejemplo:

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

Personalizar el comportamiento de visualización

Puedes cambiar el comportamiento de visualización de los mensajes dentro de la aplicación en tiempo de ejecución mediante lo siguiente:

// 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);

Configurar un listener personalizado

Si necesitas más control sobre cómo interactúa un usuario con los mensajes dentro de la aplicación, utiliza un BrazeInAppMessageListener y asígnalo a Appboy.AppboyBinding.inAppMessageListener. Para cualquier delegado que no quieras utilizar, simplemente puedes dejarlo como 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!