Skip to content

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

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

前提条件

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

カスタムスタイル

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

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

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

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

1
2
3
  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: アプリ内メッセージがアクティビティのビューから削除された直後に呼び出されます。この時点では、アプリ内メッセージはユーザーに表示されなくなります。

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

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

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

  • 閉じるボタンをクリックする
  • カスタムイベントを発火する
  • HTMLアプリ内メッセージ内のURLをクリックする
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;
  }
}
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()を呼び出して、BrazeInAppMessageManagerにデフォルトのリスナーの代わりにカスタムのIInAppMessageManagerListenerを使用するよう指示します。他の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では、アプリ内メッセージでlogClicklogImpressionを呼び出し、没入型のアプリ内メッセージではlogButtonClickを呼び出すことで行います。

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

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

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メッセージは画面にスライドし、fullmodalメッセージはフェードインおよびフェードアウトします。アプリ内メッセージにカスタムアニメーションの動作を定義したい場合、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()を呼び出して、BrazeInAppMessageManagerにデフォルトのビューファクトリの代わりにカスタムのIInAppMessageViewFactoryを使用するよう指示します。

仕組み

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

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

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

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

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

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

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

カスタムスタイル

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
}

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

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

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

@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クラスに実装しています。

1
2
3
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.InAppMessageclickActionプロパティはデフォルトで.noneに設定されていますが、次のいずれかの値に設定できます。

ClickAction クリック時の動作
.url(URL, useWebView: Bool) 指定されたURLを外部ブラウザで開きます。useWebViewtrueに設定されている場合、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

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

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

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

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

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

アプリ内メッセージの向きをカスタマイズできます。すべてのメッセージに対して新しいデフォルトの向きを設定することも、単一のメッセージに対してカスタムの向きを設定することもできます。

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

たとえば、縦向きをデフォルトの向きに設定するには:

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

単一のメッセージの向きを設定するには、Braze.InAppMessageorientationプロパティを変更します。

// 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 メッセージは破棄され、表示されません。

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

FullFullImage、およびHTMLアプリ内メッセージについて、SDKではステータスバーがデフォルトで非表示になります。他の種類のアプリ内メッセージでは、ステータスバーは変更されません。この動作を設定するには、inAppMessage(_:prepareWith:) デリゲートメソッドを使用してPresentationContextstatusBarHideBehaviorプロパティを設定します。このフィールドの値は次のいずれかになります。

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

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

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

ボタンがあるアプリ内メッセージタイプでは、buttonsプロパティに追加のthemesオブジェクトがあります。ボタンでダークモードスタイルが採用されないようにするには、map(_:)を使用してdarkテーマがないlightテーマのボタンの新しい配列を作成できます。

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

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

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

ステップ 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 メソッドを呼び出して、アプリ内メッセージがトリガーされたときにSDKに inAppMessageReceived イベントを発行させることで、JavaScriptレイヤーのアプリ内メッセージデータにアクセスできます。アプリ内メッセージがトリガーされてリスナーによって受信されたときに独自のコードを実行するには、このメソッドにコールバックを渡します。

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

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

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

組み込み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が作成されて割り当てられます。BrazeInAppMessageUIBrazeInAppMessagePresenter プロトコルの実装であり、受信したアプリ内メッセージの処理をカスタマイズするために使用できる delegate プロパティが付属しています。

  1. こちらのiOSの記事で説明されているように、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;

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

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

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

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

ユーザーがアプリ内メッセージを操作する方法をより細かくコントロールする必要がある場合は、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!