Skip to content

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 de Web 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 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 las cabeceras de un mensaje dentro de la aplicación aparezcan en cursiva:

1
2
3
  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.

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

Personalización de la desestimación 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.

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

Abrir enlaces en una pestaña nueva

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.

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

Requisitos previos

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

Configuración de oyentes personalizados del administrador

Aunque el oyente BrazeInAppMessageManager puede gestionar automáticamente la visualización y el ciclo de vida de los mensajes dentro de la aplicación, tendrás que implementar un oyente de administrador personalizado si deseas personalizar completamente tus mensajes.

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

Este oyente se aplica tanto a mensajes creados con HTML personalizado como a 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 HTML personalizados y DnD, no pasan por el flujo del oyente 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 campañas de formas inesperadas.

Paso 1: Implementar el oyente del administrador personalizado

Paso 1.1: Implementar IInAppMessageManagerListener

Crea una clase que implemente IInAppMessageManagerListener.

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

IInAppMessageManagerListener también incluye métodos delegados para clics en mensajes y botones, que pueden utilizarse en casos como la interceptación de un mensaje cuando se hace clic en un botón o mensaje para su posterior procesamiento.

Paso 1.2: Conéctate a los métodos del ciclo de vida de la vista IAM (opcional)

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

  1. beforeInAppMessageViewOpened: Se llama justo antes de que el mensaje dentro de la aplicación se añada a la vista de la actividad. El mensaje dentro de la aplicación todavía no es visible para el usuario en este momento.
  2. afterInAppMessageViewOpened: Se llama justo después de añadir el mensaje dentro de la aplicación a la vista de la actividad. El mensaje dentro de la aplicación ya es visible para el usuario en este momento.
  3. beforeInAppMessageViewClosed: Se llama 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 sigue siendo visible para el usuario en este momento.
  4. afterInAppMessageViewClosed: Se invoca justo después de que el mensaje dentro de la aplicación se elimine 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 activará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 de un mensaje HTML dentro de la aplicación
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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: Indica a Braze que utilice el oyente del administrador personalizado

Después de crear IInAppMessageManagerListener, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener() para indicar a BrazeInAppMessageManager que utilice tu IInAppMessageManagerListener personalizado en lugar del oyente predeterminado. Hazlo en tu Application.onCreate() antes de cualquier otra llamada a Braze, para que el oyente personalizado se configure antes de que se muestren los mensajes dentro de la aplicación.

Alterar los mensajes dentro de la aplicación antes de mostrarlos

Cuando se reciba un nuevo mensaje dentro de la aplicación y ya se esté mostrando un mensaje dentro de la aplicación, el nuevo mensaje se colocará en la parte superior de la pila y se podrá mostrar más adelante.

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

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

El valor de retorno 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 distraigan de la experiencia de la aplicación del usuario.

Consulta InAppMessageOperation para más detalles.

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

Una vez creado tu IHtmlInAppMessageActionListener, llama a BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener() para indicar a BrazeInAppMessageManager que utilice tu IHtmlInAppMessageActionListener personalizado en lugar del oyente de acciones predeterminado.

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

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

Configuración de fábricas personalizadas

Puedes anular una serie de valores predeterminados mediante objetos de fábrica personalizados. Se pueden registrar con el SDK de Braze según sea necesario para conseguir los resultados deseados. Sin embargo, si decides anular una fábrica, es probable que tengas que delegar explícitamente en el valor predeterminado o volver a implementar la funcionalidad proporcionada por el valor predeterminado 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

1
2
3
4
5
6
7
8
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

1
2
3
4
5
6
7
8
9
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 quieres definir completamente el aspecto visual de tus mensajes dentro de la aplicación en lugar de utilizar un tipo predeterminado, Braze lo hace posible configurando una fábrica de vistas personalizada.

BrazeInAppMessageManager se encarga automáticamente de colocar el modelo de mensajes dentro de la aplicación en la jerarquía de vistas de actividad existente de forma predeterminada utilizando DefaultInAppMessageViewWrapper. Si necesitas personalizar la forma en que se colocan los mensajes dentro de la aplicación en la jerarquía de vistas, debes utilizar un IInAppMessageViewWrapperFactory personalizado.

Los mensajes dentro de la aplicación tienen un comportamiento de animación preestablecido. Los mensajes Slideup se deslizan dentro de la pantalla; los mensajes full y modal aparecen y desaparecen gradualmente. Si quieres 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 de mensajes dentro de la aplicación. La forma más sencilla de implementar un IInAppMessageViewWrapper personalizado es extender el DefaultInAppMessageViewWrapper predeterminado:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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();
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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: Indica a Braze que utilice la fábrica

Una vez creado tu IInAppMessageViewFactory, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory() para indicar a BrazeInAppMessageManager que utilice tu IInAppMessageViewFactory personalizado en lugar de la fábrica de vistas predeterminada.

Cómo funciona

La vista de mensajes 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 añadir oyentes de clics a tu vista personalizada cuando proceda. Todas las clases de vista de Braze extienden la clase View de Android.

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

Una vez creado tu IInAppMessageViewWrapper, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory() para indicar a BrazeInAppMessageManager que utilice tu IInAppMessageViewWrapperFactory personalizado en lugar de la fábrica de envoltorios de vista predeterminada.

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

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

Una vez creado tu IInAppMessageAnimationFactory, llama a BrazeInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory() para indicar a BrazeInAppMessageManager que utilice tu IInAppMessageAnimationFactory personalizado en lugar de la fábrica de animaciones predeterminada.

Te recomendamos que configures 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 un aspecto predeterminado que se ajusta a las directrices de la interfaz de usuario estándar de Android y proporciona una experiencia fluida. Este artículo de referencia trata sobre el estilo personalizado de la mensajería dentro de la aplicación para tu aplicación Android o FireOS.

Establecer un estilo predeterminado

Puedes ver los estilos predeterminados en el archivo styles.xml del SDK de Braze:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  <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 anular estos estilos para crear un aspecto que se adapte mejor a tu aplicación.

Para anular un estilo, cópialo en su totalidad en el archivo styles.xml de tu proyecto y haz modificaciones. Debes copiar todo el estilo en tu archivo local styles.xml para que todos los atributos estén correctamente configurados. Ten en cuenta que estos estilos personalizados son para cambios en elementos individuales de la interfaz de usuario, no para 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 utilizarla, anula el estilo del texto del mensaje, los encabezados y el texto del botón, y utiliza el atributo fontFamily para indicar a Braze que utilice tu familia de fuentes personalizada.

Por ejemplo, para actualizar la fuente del texto de tu botón de mensajes dentro de la aplicación, anula 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.

Aquí tienes un ejemplo truncado con una familia de fuentes personalizada, my_custom_font_family, a la que se hace referencia en la última línea:

1
2
3
4
5
6
7
  <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 de los mensajes es Braze.InAppMessage.Message y el estilo para los encabezados de los mensajes es Braze.InAppMessage.Header. Si quieres utilizar tu familia de fuentes personalizada en todo el texto posible de los mensajes dentro de la aplicación, puedes establecer tu familia de fuentes en el estilo Braze.InAppMessage, que es el estilo padre de todos los mensajes dentro de la aplicación.

Descarte de mensajes

Deslizar para descartar mensajes de deslizamiento hacia arriba

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

  • Deslizar hacia la izquierda o hacia la derecha: Descarta el deslizamiento hacia arriba independientemente de su posición.
  • Deslizamiento hacia arriba desde la parte inferior: Deslizar de arriba hacia abajo descarta el mensaje. Deslizar de abajo hacia arriba no lo descarta.
  • Deslizamiento hacia arriba desde la parte superior: 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 solo se aplica a los mensajes de deslizamiento hacia arriba dentro de la aplicación. Los mensajes modales y completos dentro de la aplicación no admiten la función de deslizar para descartar. Para personalizar este comportamiento, puedes implementar una fábrica de envoltorios de vista personalizados.

Desactivar el descarte mediante el botón Atrás

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 con toque externo

De forma predeterminada, descartar la ventana modal con un toque externo está configurado en false. Si estableces este valor en true, el mensaje modal dentro de la aplicación se descartará cuando el usuario pulse fuera del mensaje dentro de la aplicación. Este comportamiento se puede alternar llamando a:

1
BrazeInAppMessageManager.getInstance().setClickOutsideModalViewDismissInAppMessageView(true)

Personalización de la orientación

Para establecer una orientación fija para un mensaje dentro de la aplicación, primero configura un oyente personalizado del administrador de mensajes dentro de la aplicación. A continuación, actualiza la orientación del objeto IInAppMessage en el método delegado beforeInAppMessageDisplayed():

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

Para dispositivos de tableta, los mensajes dentro de la aplicación aparecerán en el estilo de orientación preferido por el 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:

1
2
3
4
5
6
7
@Override
public InAppMessageOperation beforeInAppMessageDisplayed(IInAppMessage inAppMessage) {
  if (inAppMessage instanceof IInAppMessageThemeable && ViewUtils.isDeviceInNightMode(BrazeInAppMessageManager.getInstance().getApplicationContext())) {
    ((IInAppMessageThemeable) inAppMessage).enableDarkTheme();
  }
  return InAppMessageOperation.DISPLAY_NOW;
}
1
2
3
4
5
6
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, Braze no admite actualmente las solicitudes de reseña personalizadas de Google Play. Aunque algunos usuarios han podido integrar estas solicitudes con éxito, otros han mostrado bajas tasas de éxito debido a las cuotas de Google Play. Realiza la integración bajo tu propia responsabilidad. Consulta la documentación sobre las solicitudes de reseña dentro de la aplicación en Google Play.

Requisitos previos

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

Configuración del delegado de la interfaz de usuario (obligatorio)

Para personalizar la presentación de los mensajes dentro de la aplicación y reaccionar ante diversos eventos del ciclo de vida, deberás configurar BrazeInAppMessageUIDelegate. Este es un protocolo delegado que se utiliza para recibir y procesar cargas útiles de mensajes dentro de la aplicación, recibir eventos del ciclo de vida de la pantalla y controlar la sincronización de la pantalla. Para utilizarloBrazeInAppMessageUIDelegate, debes:

  • Utiliza la implementación BrazeInAppMessageUIpredeterminada como tu inAppMessagePresenter.
  • Incluye laBrazeUIbiblioteca en tu proyecto.

Paso 1: Implementar elBrazeInAppMessageUIDelegateprotocolo.

Primero, implementa el protocolo BrazeInAppMessageUIDelegate y los métodos correspondientes que desees. En nuestro ejemplo siguiente, estamos implementando este protocolo en la clase AppDelegate de nuestra aplicación.

1
2
3
extension AppDelegate: BrazeInAppMessageUIDelegate {
  // Implement your protocol methods here.
}
1
2
3
4
5
6
7
@interface AppDelegate () <BrazeInAppMessageUIDelegate>

@end

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

Paso 2: Asignar eldelegateobjeto

Asigna eldelegateobjeto en laBrazeInAppMessageUIinstancia antes de asignar esta interfaz de usuario de mensajes dentro de la aplicación como tu inAppMessagePresenter.

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

Comportamiento al hacer clic

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

Tipos de acción clic

La propiedad clickAction de tu Braze.InAppMessage está predeterminada a .none, pero puede ajustarse a uno de los siguientes valores:

Personalización del comportamiento al hacer clic

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

1
2
3
4
5
6
7
8
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.

Manejo del comportamiento personalizado

El siguiente métodoBrazeInAppMessageUIDelegate delegado se invoca cuando un usuario hace clic en un mensaje dentro de la aplicación. Esta devolución de llamada se activa cuando tú haces clic en los botones de mensajes dentro de la aplicación y en los botones de mensajes HTML dentro de la aplicación (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 desencadenados a través de brazeBridge.logClick().

1
2
3
4
5
6
7
func inAppMessage(
  _ ui: BrazeInAppMessageUI,
  shouldProcess clickAction: Braze.InAppMessage.ClickAction,
  buttonId: String?,
  message: Braze.InAppMessage,
  view: InAppMessageView
) -> Bool
1
2
3
4
5
6
- (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 seguir ejecutando la acción de clic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (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 descartar mensajes de deslizamiento hacia arriba

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

  • Desliza hacia la izquierda o hacia la derecha: Cierra la ventana de deslizamiento hacia arriba independientemente de su posición.
  • Deslizamiento hacia arriba desde la parte inferior: Deslizando el dedo de arriba abajo se descarta el mensaje. Deslizar el dedo de abajo hacia arriba no lo cierra.
  • Deslizamiento hacia arriba desde la parte superior: Desliza el dedo de abajo hacia arriba para descartar el mensaje. Deslizar el dedo de arriba abajo no lo elimina.

Este comportamiento de deslizamiento está integrado de forma predeterminada BrazeInAppMessageUISlideupView y solo se aplica a los mensajes de deslizamiento hacia arriba dentro de la aplicación. Los mensajes modales y completos dentro de la aplicación no admiten la función de deslizar para descartar. Para personalizar aún más la vista de deslizamiento hacia arriba, incluido el comportamiento al deslizar, puedes modificar elSlideupView.Attributes o proporcionar una vista personalizada mediante subclases.

Personalización de cierres modales personalizados

Para habilitar los descartes por toque externo, 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 dentro de la aplicación con imágenes modales, puedes configurar lo siguiente:

1
BrazeInAppMessageUI.ModalImageView.Attributes.defaults.dismissOnBackgroundTap = true

La personalización a través de Attributes no está disponible en Objective-C.

El valor predeterminado es false. Determina si el mensaje modal dentro de la aplicación se descartará cuando el usuario pulse fuera del mensaje dentro de la aplicación.

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

Personalización de la orientación de los mensajes

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 establecer una orientación personalizada para un solo mensaje.

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

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

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

Para establecer la orientación de un solo mensaje, modifica laorientationpropiedad de Braze.InAppMessage:

1
2
3
4
5
6
7
8
// 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
1
2
3
4
5
6
7
8
// 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 en la orientación del dispositivo mientras el mensaje sigue mostrándose hará que el mensaje gire con el dispositivo (siempre que lo permita la configuración orientationdel mensaje).

La orientación del dispositivo también debe ser compatible con la propiedad orientationdel mensaje dentro de la aplicación para que este se muestre. Además, la configuración de preferredOrientation sólo se respetará si está incluida en las orientaciones de interfaz admitidas de tu aplicación en la sección Información de despliegue de la configuración de tu objetivo 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 momentos de tu experiencia de usuario. Si hay situaciones en las que no quieres 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 la temporización del mensaje dentro de la aplicación, utiliza el método delegado inAppMessage(_:displayChoiceForMessage:) para establecer la propiedad BrazeInAppMessageUI.DisplayChoice.

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

Configura BrazeInAppMessageUI.DisplayChoice para que devuelva uno de los siguientes valores:

Ocultar la barra de estado

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

Desactivar el modo oscuro

Para evitar que los mensajes dentro de la aplicación adopten el estilo de modo oscuro cuando el dispositivo del usuario tiene habilitado el modo oscuro, implementa el método delegado inAppMessage(_:prepareWith:). El PresentationContext pasado 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 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 mensaje dentro de la aplicación con botones tienen un objeto themes adicional en su propiedad buttons. Para evitar que los botones adopten el estilo de modo oscuro, puedes utilizar map(_:) para crear una nueva serie de botones con un tema light y sin tema dark.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (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 el mensaje de revisión de la tienda de aplicaciones

Puedes utilizar mensajes dentro de la aplicación en una campaña para pedir a los usuarios que dejen una reseña en la App Store.

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

En primer lugar, configura el BrazeInAppMessageUIDelegate en tu aplicación.

Paso 2: Desactiva el mensaje predeterminado de revisión de la App Store

A continuación, implementa el método delegado inAppMessage(_:displayChoiceForMessage:) para desactivar el mensaje predeterminado de revisión de la App Store.

1
2
3
4
5
6
7
8
9
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
  }
}
1
2
3
4
5
6
7
8
9
- (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;
  }
}

Paso 3: Crear un vínculo profundo

En tu código de gestión de vínculos profundos, añade el siguiente código para procesar el vínculo profundo {YOUR-APP-SCHEME}:app-store-review. Ten en cuenta que tendrás que importar StoreKit para utilizar SKStoreReviewController:

1
2
3
4
5
6
7
8
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  let urlString = url.absoluteString.removingPercentEncoding
  if (urlString == "{YOUR-APP-SCHEME}:app-store-review") {
    SKStoreReviewController.requestReview()
    return true;
  }
  // Other deep link handling code…
}
1
2
3
4
5
6
7
8
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  NSString *urlString = url.absoluteString.stringByRemovingPercentEncoding;
  if ([urlString isEqualToString:@"{YOUR-APP-SCHEME}:app-store-review"]) {
    [SKStoreReviewController requestReview];
    return YES;
  }
  // Other deep link handling code…
}

Paso 4: Establece un comportamiento personalizado al hacer clic

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

  • El par clave-valor "AppStore Review" : "true"
  • El comportamiento al hacer clic configurado a “Enlace profundo dentro de la aplicación”, utilizando el enlace profundo {YOUR-APP-SCHEME}:app-store-review.

Requisitos previos

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

Métodos de registro

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

Tratamiento de datos de mensajes

En la mayoría de los casos, puedes utilizar el método Braze.addListener para registrar escuchadores de eventos que gestionen los datos procedentes de 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 sea desencadenado y recibido por el oyente.

Para personalizar cómo se gestionan los datos de los mensajes, consulta los siguientes ejemplos de implementación:

Para mejorar el comportamiento predeterminado, o si no tienes acceso a personalizar el código nativo de iOS o Android, te recomendamos que desactives la interfaz de usuario predeterminada mientras sigues recibiendo eventos de mensajes dentro de la aplicación desde Braze. Para desactivar la interfaz 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 predeterminada.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 mensajes dentro de la aplicación a través de la capa nativa.

Implementa el IInAppMessageManagerListener tal y como se describe en nuestro artículo de Android sobre la escucha personalizada del administrador. En tu implementación de beforeInAppMessageDisplayed, puedes acceder a los datos de inAppMessage, enviarlos a la capa JavaScript y decidir mostrar o no el mensaje nativo en función del valor devuelto.

Para más información sobre estos valores, consulta nuestra documentación de Android.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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;
}

Anular el delegado de interfaz predeterminado

Por predeterminado, BrazeInAppMessageUI se crea y asigna cuando inicializas la instancia 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 artículo sobre iOS aquí.

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

Para más detalles sobre estos valores, consulta nuestra documentación sobre iOS.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (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 braze.

1
2
3
4
5
6
7
8
@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;
}

Sobreescribir 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, sigue el protocolo BrazeInAppMessagePresenter y asigna tu presentador personalizado siguiendo el siguiente ejemplo:

1
2
3
4
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:

1
2
3
4
5
6
7
8
// 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);

Configuración de una escucha personalizada

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 los delegados que no quieras utilizar, puedes dejarlos simplemente como null.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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!