コンテンツにスキップ

アプリ内メッセージをカスタマイズする

Braze SDKのアプリ内メッセージをカスタマイズする方法を説明します。高度なスタイル設定については、キーと値のペアを使ってメッセージのスタイルをカスタマイズするチュートリアルを参照してください。

前提条件

この機能を使用する前に、Web Braze SDKを統合する必要があります。

カスタムスタイル

BrazeのUI要素はデフォルトの外観と操作感を備えており、ニュートラルなアプリ内メッセージ体験を提供し、他のBrazeモバイルプラットフォームとの一貫性を目指しています。デフォルトのBrazeスタイルは、Braze SDK内のCSSで定義されています。

デフォルトスタイルの設定

アプリケーションで選択したスタイルを上書きすることで、独自の背景画像、フォントファミリ、スタイル、サイズ、アニメーションなどを使用して標準アプリ内メッセージタイプをカスタマイズできます。

たとえば、次の例はアプリ内メッセージのヘッダーをイタリックで表示する上書きを示しています。

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

詳細についてはJSDocsを参照してください。

z-indexをカスタマイズする

デフォルトでは、アプリ内メッセージは z-index: 9001 を使用して表示されます。Webサイトがそれよりも高い値で要素をスタイルしているシナリオでは、inAppMessageZIndex 初期化オプションを使用して設定できます。

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

メッセージの閉じ方をカスタマイズする

デフォルトでは、アプリ内メッセージが表示されているときにエスケープキーを押すか、ページのグレーアウトした背景をクリックすると、メッセージが閉じられます。requireExplicitInAppMessageDismissal 初期化オプションをtrueに設定すると、この動作を無効にし、メッセージを閉じるために明示的なボタンクリックを必要とするようにできます。

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

表示タイミングをカスタマイズする

デフォルトの表示タイミングを上書きするには、braze.automaticallyShowInAppMessages() の呼び出しを削除し、braze.subscribeToInAppMessage() でメッセージを処理します。braze.openSession() の前にコールバックを登録することで、セッション開始メッセージをインターセプトし、各メッセージを表示するか延期するかを決定できます。

デフォルトでは、Brazeはアプリ内メッセージがトリガーされ、表示対象となったときに表示します。アプリ体験に異なる動作が必要な場合は、カスタムコールバックを使用して、独自のロジックに基づいてメッセージを延期または表示できます。

次の例は、トリガーされたアプリ内メッセージをサブスクライブし、選択したメッセージを延期し、延期したメッセージを後で表示する方法を示しています。

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

関連する配信カスタマイズのガイダンスについては、以下を参照してください。

アプリ内メッセージのリンクを新しいタブで開くように設定するには、openInAppMessagesInNewTab オプションを true に設定して、アプリ内メッセージのクリックによるすべてのリンクが新しいタブまたはウィンドウで開くようにします。

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

前提条件

この機能を使用する前に、Android Braze SDKを統合する必要があります。 アプリ内メッセージの設定も必要です。

カスタムマネージャーリスナーを設定する

BrazeInAppMessageManagerリスナーはアプリ内メッセージの表示とライフサイクルを自動的に処理できますが、メッセージを完全にカスタマイズしたい場合は、カスタムマネージャーリスナーを実装する必要があります。

Braze SDKにはデフォルトのDefaultHtmlInAppMessageActionListenerクラスがあり、カスタムリスナーが定義されていない場合に使用され、適切なアクションを自動的に実行します。カスタムHTMLアプリ内メッセージ内のさまざまなボタンとのユーザーインタラクションをより細かくコントロールする必要がある場合は、カスタムIHtmlInAppMessageActionListenerクラスを実装してください。

このリスナーは、カスタムHTMLで構築されたメッセージとドラッグ&ドロップ(DnD)エディターで作成されたメッセージの__両方__に適用されます。従来のIAMには適用されません。従来のIAMは、Brazeの組み込みでSDKがレンダリングするメッセージタイプ(スライドアップ、モーダル、フルなど)であり、事前定義されたレイアウトを使用してオリジナルのアプリ内メッセージ作成画面で作成されます。カスタムHTMLやDnD IAMとは異なり、HTMLアクションリスナーフローを通過しません。

カスタムIHtmlInAppMessageActionListenerを設定すると、そのロジックは_すべて_のDnDメッセージのデフォルトのクリック動作を上書きします。マーケティングチームのキャンペーンに予期しない影響を与える可能性があるため、この点をチームに必ず伝えてください。

ステップ1:カスタムマネージャーリスナーを実装する

ステップ1.1:IInAppMessageManagerListenerを実装する

IInAppMessageManagerListenerを実装するクラスを作成します。

IInAppMessageManagerListenerのコールバックは、アプリ内メッセージのライフサイクルのさまざまなポイントでも呼び出されます。たとえば、Brazeからアプリ内メッセージを受信したときにカスタムマネージャーリスナーを設定している場合、beforeInAppMessageDisplayed()メソッドが呼び出されます。このメソッドの実装がInAppMessageOperation.DISCARDを返した場合、アプリ内メッセージがホストアプリによって処理され、Brazeで表示すべきではないことをBrazeに通知します。InAppMessageOperation.DISPLAY_NOWが返された場合、Brazeはアプリ内メッセージの表示を試みます。このメソッドは、カスタマイズした方法でアプリ内メッセージを表示する場合に使用してください。

IInAppMessageManagerListenerには、メッセージのクリックやボタンのデリゲートメソッドも含まれており、ボタンやメッセージがクリックされたときにメッセージをインターセプトしてさらに処理するなどのケースで使用できます。

ステップ1.2:IAMビューのライフサイクルメソッドにフックする(オプション)

IInAppMessageManagerListenerインターフェイスには、アプリ内メッセージビューのライフサイクルの異なるポイントで呼び出されるアプリ内メッセージビューメソッドがあります。これらのメソッドは以下の順序で呼び出されます。

  1. beforeInAppMessageViewOpened: アプリ内メッセージがアクティビティのビューに追加される直前に呼び出されます。この時点では、アプリ内メッセージはまだユーザーに表示されていません。
  2. afterInAppMessageViewOpened: アプリ内メッセージがアクティビティのビューに追加された直後に呼び出されます。この時点で、アプリ内メッセージがユーザーに表示されています。
  3. beforeInAppMessageViewClosed: アプリ内メッセージがアクティビティのビューから削除される直前に呼び出されます。この時点では、アプリ内メッセージはまだユーザーに表示されています。
  4. afterInAppMessageViewClosed: アプリ内メッセージがアクティビティのビューから削除された直後に呼び出されます。この時点で、アプリ内メッセージはユーザーに表示されていません。

afterInAppMessageViewOpenedとbeforeInAppMessageViewClosedの間が、アプリ内メッセージビューが画面上に表示され、ユーザーに見える状態の時間です。

IHtmlInAppMessageActionListenerを実装するクラスを作成します。

IHtmlInAppMessageActionListenerのコールバックは、ユーザーがHTMLアプリ内メッセージ内で以下のいずれかのアクションを実行するたびに呼び出されます。

  • 閉じるボタンをクリック
  • カスタムイベントを発火
  • HTMLアプリ内メッセージ内のURLをクリック
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
    }
}

ステップ2:Brazeにカスタムマネージャーリスナーを使用するよう指示する

IInAppMessageManagerListenerを作成したら、BrazeInAppMessageManager.getInstance().setCustomInAppMessageManagerListener()を呼び出して、デフォルトリスナーの代わりにカスタムIInAppMessageManagerListenerを使用するようBrazeInAppMessageManagerに指示します。これは、Brazeへの他の呼び出しの前にApplication.onCreate()で行い、アプリ内メッセージが表示される前にカスタムリスナーが設定されるようにしてください。

表示前にアプリ内メッセージを変更する

新しいアプリ内メッセージを受信したときに、すでにアプリ内メッセージが表示されている場合、新しいメッセージはスタックの先頭に追加され、後で表示できます。

ただし、表示中のアプリ内メッセージがない場合は、IInAppMessageManagerListenerの以下のデリゲートメソッドが呼び出されます。

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

InAppMessageOperation()の戻り値によって、メッセージをいつ表示するかをコントロールできます。このメソッドの推奨される使い方は、アプリ内メッセージがユーザーのアプリ体験を妨げるようなアプリの特定の部分で、DISPLAY_LATERを返してメッセージを遅延表示することです。

InAppMessageOperationの戻り値 動作
DISPLAY_NOW メッセージが表示されます
DISPLAY_LATER メッセージがスタックに戻され、次の利用可能なタイミングで表示されます
DISCARD メッセージが破棄されます
null メッセージが無視されます。このメソッドはnullを返すべきではありません

詳しくはInAppMessageOperationを参照してください。

Androidでは、アプリ内メッセージでlogClickとlogImpressionを呼び出し、没入型アプリ内メッセージでlogButtonClickを呼び出すことで実行します。

IHtmlInAppMessageActionListenerを作成したら、BrazeInAppMessageManager.getInstance().setCustomHtmlInAppMessageActionListener()を呼び出して、デフォルトのアクションリスナーの代わりにカスタムIHtmlInAppMessageActionListenerを使用するようBrazeInAppMessageManagerに指示します。

IHtmlInAppMessageActionListenerは、Brazeへの他の呼び出しの前にApplication.onCreate()で設定することをお勧めします。これにより、アプリ内メッセージが表示される前にカスタムアクションリスナーが設定されます。

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

カスタムファクトリーの設定

カスタムファクトリーオブジェクトを使って、多くのデフォルト設定をオーバーライドできます。これらは必要に応じてBraze SDKに登録し、目的の結果を得ることができます。ただし、ファクトリーをオーバーライドする場合は、デフォルトに明示的に委譲するか、Brazeのデフォルトが提供する機能を再実装する必要がある場合が多いです。以下のコードスニペットでは、IInAppMessageViewFactoryインターフェイスとIInAppMessageViewWrapperFactoryインターフェイスのカスタム実装を提供する方法を説明します。

アプリ内メッセージタイプ

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

アプリ内メッセージタイプ

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

Brazeのアプリ内メッセージタイプは、ほとんどのカスタムユースケースに対応できるほど汎用的です。ただし、デフォルトタイプを使用する代わりにアプリ内メッセージの外観を完全に定義したい場合、Brazeではカスタムビューファクトリーを設定することでそれが可能です。

BrazeInAppMessageManagerは、デフォルトでDefaultInAppMessageViewWrapperを使用して、アプリ内メッセージモデルを既存のアクティビティビュー階層に自動的に配置します。アプリ内メッセージをビュー階層に配置する方法をカスタマイズする必要がある場合は、カスタムIInAppMessageViewWrapperFactoryを使用してください。

アプリ内メッセージにはプリセットのアニメーション動作があります。Slideupメッセージは画面にスライドインし、fullとmodalメッセージはフェードイン・フェードアウトします。アプリ内メッセージにカスタムアニメーション動作を定義したい場合、Brazeではカスタムアニメーションファクトリーを設定することでそれが可能です。

ステップ1:ファクトリーを実装する

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

IInAppMessageViewWrapperFactoryを実装し、IInAppMessageViewWrapperを返すクラスを作成します。

このファクトリーは、アプリ内メッセージビューが作成された直後に呼び出されます。カスタムIInAppMessageViewWrapperを実装する最も簡単な方法は、デフォルトのDefaultInAppMessageViewWrapperを拡張することです。

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

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

ステップ2:ファクトリーを使用するようBrazeに指示する

IInAppMessageViewFactoryを作成したら、BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewFactory()を呼び出して、デフォルトのビューファクトリーの代わりにカスタムIInAppMessageViewFactoryを使用するようBrazeInAppMessageManagerに指示します。

仕組み

slideupアプリ内メッセージビューはIInAppMessageViewを実装しています。fullおよびmodalタイプのメッセージビューはIInAppMessageImmersiveViewを実装しています。これらのクラスのいずれかを実装することで、Brazeは適切な場所でカスタムビューにクリックリスナーを追加できます。すべてのBrazeビュークラスはAndroidのViewクラスを拡張しています。

IInAppMessageViewを実装すると、カスタムビューの特定の部分をクリック可能として定義できます。IInAppMessageImmersiveViewを実装すると、メッセージボタンビューと閉じるボタンビューを定義できます。

IInAppMessageViewWrapperを作成したら、BrazeInAppMessageManager.getInstance().setCustomInAppMessageViewWrapperFactory()を呼び出して、デフォルトのビューラッパーファクトリーの代わりにカスタムIInAppMessageViewWrapperFactoryを使用するようBrazeInAppMessageManagerに指示します。

IInAppMessageViewWrapperFactoryは、Brazeへの他の呼び出しの前にApplication.onCreate()で設定することを推奨します。これにより、アプリ内メッセージが表示される前にカスタムビューラッパーファクトリーが設定されます。

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

IInAppMessageAnimationFactoryを作成したら、BrazeInAppMessageManager.getInstance().setCustomInAppMessageAnimationFactory()を呼び出して、デフォルトのアニメーションファクトリーの代わりにカスタムIInAppMessageAnimationFactoryを使用するようBrazeInAppMessageManagerに指示します。

IInAppMessageAnimationFactoryは、Brazeへの他の呼び出しの前にApplication.onCreate()で設定することを推奨します。これにより、アプリ内メッセージが表示される前にカスタムアニメーションファクトリーが設定されます。

カスタムスタイル

Braze の UI 要素には、Android 標準の UI ガイドラインに沿ったデフォルトの外観が備わっており、シームレスなエクスペリエンスを提供します。このリファレンス記事では、Android または FireOS アプリケーションにおけるアプリ内メッセージのカスタムスタイル設定について説明します。

デフォルトスタイルを設定する

デフォルトスタイルは、Braze SDKのstyles.xmlファイルで確認できます。

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

必要に応じて、これらのスタイルをオーバーライドして、アプリにより適した外観を作成できます。

スタイルをオーバーライドするには、プロジェクトの styles.xml ファイルにスタイル全体をコピーし、変更を加えます。すべての属性が正しく設定されるように、スタイル全体をローカルの styles.xml ファイルにコピーする必要があります。これらのカスタムスタイルは個々の UI 要素の変更用であり、レイアウト全体の変更ではありません。レイアウトレベルの変更はカスタムビューで処理する必要があります。

フォントをカスタマイズする

res/font ディレクトリ内のタイプフェイスを参照してカスタムフォントを設定できます。使用するには、メッセージテキスト、ヘッダー、ボタンテキストのスタイルをオーバーライドし、fontFamily 属性を使用してカスタムフォントファミリーを使用するよう Braze に指示します。

たとえば、アプリ内メッセージのボタンテキストのフォントを更新するには、Braze.InAppMessage.Button スタイルをオーバーライドし、カスタムフォントファミリーを参照します。属性値は res/font ディレクトリ内のフォントファミリーを指定する必要があります。

以下は、最後の行でカスタムフォントファミリー my_custom_font_family を参照している簡略化された例です。

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

ボタンテキスト用の Braze.InAppMessage.Button スタイル以外にも、メッセージテキスト用のスタイルは Braze.InAppMessage.Message、メッセージヘッダー用のスタイルは Braze.InAppMessage.Header です。すべてのアプリ内メッセージテキストにカスタムフォントファミリーを使用したい場合は、すべてのアプリ内メッセージの親スタイルである Braze.InAppMessage スタイルにフォントファミリーを設定できます。

メッセージの閉じ方

スワイプでスライドアップメッセージを閉じる

デフォルトでは、スライドアップアプリ内メッセージはスワイプジェスチャーで閉じることができます。スワイプの方向は、スライドアップの位置によって異なります。

  • 左右のスワイプ:位置に関係なく、スライドアップを閉じます。
  • 下からのスライドアップ:上から下にスワイプするとメッセージが閉じます。下から上にスワイプしても閉じません。
  • 上からのスライドアップ:下から上にスワイプするとメッセージが閉じます。上から下にスワイプしても閉じません。

このスワイプ動作はデフォルトのDefaultInAppMessageViewWrapperに組み込まれており、スライドアップアプリ内メッセージにのみ適用されます。モーダルおよびフルアプリ内メッセージはスワイプで閉じる機能をサポートしていません。この動作をカスタマイズするには、カスタムビューラッパーファクトリを実装します。

戻るボタンによる閉じるを無効にする

デフォルトでは、ハードウェアの戻るボタンはBrazeアプリ内メッセージを閉じます。この動作は、BrazeInAppMessageManager.setBackButtonDismissesInAppMessageView()を使用してメッセージごとに無効にできます。

次の例では、disable_back_buttonはアプリ内メッセージに設定されたカスタムキーと値のペアで、戻るボタンでメッセージを閉じることを許可するかどうかを示します。

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

外側タップによる閉じるを有効にする

デフォルトでは、外側タップによるモーダルの閉じるはfalseに設定されています。この値をtrueに設定すると、ユーザーがアプリ内メッセージの外側をタップしたときにモーダルアプリ内メッセージが閉じられます。この動作は、以下を呼び出すことで有効に切り替えることができます。

BrazeInAppMessageManager.getInstance().setClickOutsideModalViewDismissInAppMessageView(true)

表示方向をカスタマイズする

アプリ内メッセージの表示方向を固定するには、まずカスタムアプリ内メッセージマネージャーリスナーを設定します。次に、beforeInAppMessageDisplayed() デリゲートメソッド内で IInAppMessage オブジェクトの表示方向を更新します。

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
}

タブレットデバイスの場合、アプリ内メッセージは実際の画面の向きに関係なく、ユーザーが設定した優先表示方向で表示されます。

ダークテーマを無効化する

デフォルトでは、IInAppMessageManagerListenerのbeforeInAppMessageDisplayed()はシステム設定を確認し、以下のコードでメッセージにダークテーマのスタイルを条件付きで有効にします。

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

これを変更するには、表示前のプロセスのどのステップでもenableDarkThemeを呼び出して、独自の条件付きロジックを実装できます。

Google Play レビュープロンプトのカスタマイズ

Googleが設定した制限や制約により、カスタムGoogle Playレビュープロンプトは現在Brazeではサポートされていません。一部のユーザーはこれらのプロンプトの統合に成功していますが、Google Playのクォータにより成功率が低いケースも報告されています。統合はご自身の判断で行ってください。Google Playアプリ内レビュープロンプトに関するドキュメントを参照してください。

前提条件

この機能を使用する前に、Swift Braze SDKの統合を完了する必要があります。

UIデリゲートの設定(必須)

アプリ内メッセージの表示をカスタマイズし、さまざまなライフサイクルイベントに対応するには、BrazeInAppMessageUIDelegateを設定する必要があります。これは、トリガーされたアプリ内メッセージのペイロードの受信と処理、表示ライフサイクルイベントの受信、および表示タイミングの制御に使用されるデリゲートプロトコルです。BrazeInAppMessageUIDelegateを使用するには、以下が必要です。

  • デフォルトのBrazeInAppMessageUI実装をinAppMessagePresenterとして使用します。
  • プロジェクトにBrazeUIライブラリを含めます。

ステップ1:BrazeInAppMessageUIDelegateプロトコルを実装する

まず、BrazeInAppMessageUIDelegateプロトコルと、使用したい対応メソッドを実装します。以下の例では、このプロトコルをアプリケーションのAppDelegateクラスに実装しています。

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

@end

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

ステップ2:delegateオブジェクトを割り当てる

このアプリ内メッセージUIをinAppMessagePresenterとして割り当てる前に、BrazeInAppMessageUIインスタンスにdelegateオブジェクトを割り当てます。

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

クリック時の動作

各 Braze.InAppMessage オブジェクトには、クリック時の動作を定義する対応する ClickAction が含まれています。

クリックアクションの種類

Braze.InAppMessage の clickAction プロパティはデフォルトで .none ですが、以下のいずれかの値に設定できます。

ClickAction クリック時の動作
.url(URL, useWebView: Bool) 指定されたURLを外部ブラウザで開きます。useWebView が true に設定されている場合、Webビューで開きます。
.none クリックするとメッセージが閉じられます。

クリック時の動作をカスタマイズする

この動作をカスタマイズするには、以下のサンプルを参照して clickAction プロパティを変更します。

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

inAppMessage(_:prepareWith:) メソッドはObjective-Cでは使用できません。

カスタム動作を処理する

以下の BrazeInAppMessageUIDelegate デリゲートメソッドは、ユーザーがアプリ内メッセージをクリックしたときに呼び出されます。このコールバックは、アプリ内メッセージボタンおよびHTMLアプリ内メッセージボタン(リンク)に対するユーザー主導のクリックでトリガーされ、これらの操作にはオプションパラメーターとしてボタンIDが提供されます。このコールバックは、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;

このメソッドは、Brazeがクリックアクションの実行を続行するかどうかを示すブール値を返します。

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

スライドアップメッセージをスワイプして閉じる

デフォルトでは、スライドアップのアプリ内メッセージはスワイプジェスチャーで閉じることができます。スワイプの方向はスライドアップの位置によって異なります。

  • 左または右にスワイプ:位置に関係なくスライドアップを閉じます。
  • 下からのスライドアップ:上から下へスワイプするとメッセージが閉じます。下から上へスワイプしても閉じません。
  • 上からのスライドアップ:下から上へスワイプするとメッセージが閉じます。上から下へスワイプしても閉じません。

このスワイプ動作はデフォルトのBrazeInAppMessageUI SlideupViewに組み込まれており、スライドアップのアプリ内メッセージにのみ適用されます。モーダルおよびフルのアプリ内メッセージはスワイプによる閉じる操作をサポートしていません。スワイプ動作を含むスライドアップビューをさらにカスタマイズするには、SlideupView.Attributesを変更するか、サブクラス化によりカスタムビューを提供します。

モーダルの閉じ方をカスタマイズする

外側タップによる閉じ操作を有効にするには、カスタマイズしたいアプリ内メッセージタイプのAttributes構造体のdismissOnBackgroundTapプロパティを変更します。

たとえば、モーダル画像アプリ内メッセージでこの機能を有効にする場合は、次のように設定します。

BrazeInAppMessageUI.ModalImageView.Attributes.defaults.dismissOnBackgroundTap = true

OBJECTIVE-CではAttributesによるカスタマイズは利用できません。

デフォルト値はfalseです。これは、ユーザーがアプリ内メッセージの外側をタップした場合にモーダルアプリ内メッセージを閉じるかどうかを決定します。

DismissModalOnOutsideTap 説明
true モーダルアプリ内メッセージは外側タップで閉じられます。
false デフォルト。モーダルアプリ内メッセージは外側タップで閉じられません。

アプリ内メッセージのカスタマイズの詳細については、この記事を参照してください。

メッセージの向きをカスタマイズする

アプリ内メッセージの向きをカスタマイズできます。すべてのメッセージにデフォルトの向きを設定したり、1つのメッセージにカスタムの向きを設定したりできます。

すべてのアプリ内メッセージにデフォルトの向きを設定するには、inAppMessage(_:prepareWith:) メソッドを使用して、PresentationContextのpreferredOrientationプロパティを設定します。

たとえば、ポートレートをデフォルトの向きとして設定するには:

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

1つのメッセージの向きを設定するには、Braze.InAppMessageのorientationプロパティを変更します:

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

アプリ内メッセージが表示された後、メッセージがまだ表示されている間にデバイスの向きが変わると、メッセージはデバイスに合わせて回転します(メッセージのorientation設定でサポートされている場合)。

メッセージを表示するには、アプリ内メッセージのorientationプロパティでもそのデバイスの向きがサポートされている必要があります。また、preferredOrientation設定は、Xcodeのターゲット設定のDeployment Infoセクションで、アプリケーションのサポートされるインターフェイスの向きに含まれている場合にのみ適用されます。

Xcodeでサポートされている向き。

表示タイミングをカスタマイズする

ユーザーエクスペリエンスの特定のタイミングで、利用可能なアプリ内メッセージを表示するかどうかをコントロールできます。フルスクリーンゲーム中やロード画面など、アプリ内メッセージを表示したくない状況がある場合、保留中のアプリ内メッセージを遅延させたり破棄したりできます。アプリ内メッセージのタイミングをコントロールするには、inAppMessage(_:displayChoiceForMessage:) デリゲートメソッドを使用して BrazeInAppMessageUI.DisplayChoice プロパティを設定します。

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

BrazeInAppMessageUI.DisplayChoice を設定して、以下のいずれかの値を返すようにします。

表示選択肢 動作
.now メッセージは即座に表示されます。これはデフォルト値です。
.reenqueue メッセージは表示されず、スタックの先頭に戻されます。
.later メッセージは表示されず、スタックの先頭に戻されます。(非推奨、.reenqueue を使用してください)
.discard メッセージは破棄され、表示されません。

ステータスバーを非表示にする

Full、FullImage、HTMLのアプリ内メッセージでは、SDKはデフォルトでステータスバーを非表示にします。その他のタイプのアプリ内メッセージでは、ステータスバーはそのままになります。この動作を設定するには、inAppMessage(_:prepareWith:) デリゲートメソッドを使用して、PresentationContextのstatusBarHideBehaviorプロパティを設定します。このフィールドは以下のいずれかの値を取ります。

ステータスバー非表示動作 説明
.auto メッセージビューがステータスバーの非表示状態を決定します。
.hidden 常にステータスバーを非表示にします。
.visible 常にステータスバーを表示します。

ダークモードを無効にする

ユーザーのデバイスでダークモードが有効になっているときに、アプリ内メッセージがダークモードのスタイルを適用しないようにするには、inAppMessage(_:prepareWith:) デリゲートメソッドを実装します。このメソッドに渡される PresentationContext には、表示される InAppMessage オブジェクトへの参照が含まれています。各 InAppMessage には dark と light モードのテーマを含む themes プロパティがあります。themes.dark プロパティを nil に設定すると、Brazeは自動的にライトテーマを使用してアプリ内メッセージを表示します。

ボタンを持つアプリ内メッセージタイプには、buttons プロパティに追加の themes オブジェクトがあります。ボタンがダークモードのスタイルを適用しないようにするには、map(_:) を使用して、light テーマのみを持ち 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;
  }
}

App Storeレビュープロンプトをカスタマイズする

キャンペーンでアプリ内メッセージを使用して、ユーザーにApp Storeレビューを依頼できます。

ステップ1: アプリ内メッセージデリゲートを設定する

まず、アプリでBrazeInAppMessageUIDelegateを設定します。

ステップ2: デフォルトのApp Storeレビューメッセージを無効にする

次に、inAppMessage(_:displayChoiceForMessage:) デリゲートメソッドを実装して、デフォルトの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;
  }
}

scene:openURLContexts:ハンドラーに、{YOUR-APP-SCHEME}:app-store-reviewディープリンクを処理する以下のコードを追加します。SKStoreReviewControllerを使用するにはStoreKitをインポートする必要があることに注意してください。

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

ステップ4: カスタムのクリック時動作を設定する

次に、以下の内容でアプリ内メッセージングキャンペーンを作成します。

  • キーと値のペア "AppStore Review" : "true"
  • クリック時の動作を「アプリへのディープリンク」に設定し、ディープリンク{YOUR-APP-SCHEME}:app-store-reviewを使用します。

この機能を使う前に、React Native Braze SDKを統合する必要があります。

ロギングのメソッド

BrazeInAppMessageインスタンスを渡すことで、以下のメソッドを使用して分析を記録し、アクションを実行できます。

メソッド 説明
logInAppMessageClicked(inAppMessage) 提供されたアプリ内メッセージデータのクリックを記録します。
logInAppMessageImpression(inAppMessage) 提供されたアプリ内メッセージデータのインプレッションを記録します。
logInAppMessageButtonClicked(inAppMessage, buttonId) 提供されたアプリ内メッセージデータとボタンIDのボタンクリックを記録します。
hideCurrentInAppMessage() 現在表示されているアプリ内メッセージを閉じます。
performInAppMessageAction(inAppMessage) アプリ内メッセージのアクションを実行します。
performInAppMessageButtonAction(inAppMessage, buttonId) アプリ内メッセージボタンのアクションを実行します。

メッセージデータの処理

ほとんどの場合、Braze.addListener メソッドを使用してイベントリスナーを登録し、アプリ内メッセージから送信されるデータを処理できます。

さらに、Braze.subscribeToInAppMessage メソッドを呼び出すことで、JavaScriptレイヤーでアプリ内メッセージデータにアクセスできます。このメソッドにより、アプリ内メッセージがトリガーされたときにSDKが inAppMessageReceived イベントを発行します。このメソッドにコールバックを渡すことで、アプリ内メッセージがトリガーされてリスナーが受信したときに独自のコードを実行できます。

メッセージデータの処理をカスタマイズするには、以下の実装例を参照してください。

デフォルトの動作を拡張する場合、またはネイティブのiOSやAndroidコードをカスタマイズするアクセス権がない場合は、Brazeからアプリ内メッセージイベントを引き続き受信しながら、デフォルトUIを無効にすることをお勧めします。デフォルトUIを無効にするには、Braze.subscribeToInAppMessage メソッドに false を渡し、アプリ内メッセージデータを使用してJavaScriptで独自のメッセージを構築します。デフォルトUIを無効にする場合は、メッセージの分析を手動でログに記録する必要があることに注意してください。

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

組み込みUIを使用してアプリ内メッセージを表示するかどうかを判断するより高度なロジックを組み込むには、ネイティブレイヤーを通じてアプリ内メッセージを実装します。

Androidのカスタムマネージャーリスナーの記事で説明されているように、IInAppMessageManagerListener を実装します。beforeInAppMessageDisplayed の実装では、inAppMessage データにアクセスし、JavaScriptレイヤーに送信し、戻り値に基づいてネイティブメッセージを表示するかどうかを決定できます。

これらの値の詳細については、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;
}

デフォルトUIデリゲートのオーバーライド

デフォルトでは、braze インスタンスを初期化すると BrazeInAppMessageUI が作成されて割り当てられます。BrazeInAppMessageUI は BrazeInAppMessagePresenter プロトコルの実装であり、受信したアプリ内メッセージの処理をカスタマイズするために使用できる delegate プロパティが含まれています。

  1. iOSアプリ内メッセージUIチュートリアルで説明されているように、BrazeInAppMessageUIDelegate デリゲートを実装します。

  2. inAppMessage(_:displayChoiceForMessage:) デリゲートメソッドで、inAppMessage データにアクセスし、JavaScriptレイヤーに送信し、戻り値に基づいてネイティブメッセージを表示するかどうかを決定できます。

これらの値の詳細については、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;
}

このデリゲートを使用するには、braze インスタンスを初期化した後に brazeInAppMessagePresenter.delegate に割り当てます。

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

デフォルトネイティブUIのオーバーライド

ネイティブiOSレイヤーでアプリ内メッセージの表示を完全にカスタマイズする場合は、BrazeInAppMessagePresenter プロトコルに準拠し、以下のサンプルに従ってカスタムプレゼンターを割り当てます。

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

表示動作をカスタマイズする

アプリ内メッセージの表示動作は、以下の方法で実行時に変更できます。

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

カスタムリスナーを設定する

ユーザーがアプリ内メッセージとやり取りする方法をより細かく制御する必要がある場合は、BrazeInAppMessageListenerを使用してAppboy.AppboyBinding.inAppMessageListenerに割り当てます。使用しないデリゲートについては、単に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!