In-App Messaging

In-app messages are toaster-style, foreground-only messages rendered by the SDK. They do not require OS-level notification permission.

This guide explains how in-app messaging works, how to start and stop the message surface, how to respond to lifecycle events through the delegate, and how to configure campaigns in ZMP. In-app messages are ideal for highly contextual, low-urgency communication with close to 100% deliverability across your install base.

The SDK renders the in-app UI itself — your app does not wire up a view. The SDK exposes lifecycle callbacks so you can react when a message appears, is clicked, or is dismissed.

Note: In-app messages are a different surface from push notifications. Push notifications are delivered by the OS while the app is in the background; in-app messages are rendered by the SDK while the app is in the foreground. See Push Notifications for the push surface.

On this page

How it works

The SDK uses a polling mechanism to fetch in-app messages. When a message is received, the SDK evaluates the app state to determine whether to display it. If the conditions are met, an in-app message is shown.

To monitor the lifecycle of a message (will appear, did appear, clicked, dismissed), implement ZTInAppMessageDelegate and register it with ZetaClient.

Start and stop in-app messaging

In-app messaging is enabled by default. To stop displaying in-app messages:

ZetaClient.shared.inApp?.stop()
[[ZetaClient shared].inApp stop];

To restart:

ZetaClient.shared.inApp?.start()
[[ZetaClient shared].inApp start];

Note: The SDK does not persist the stop state; your app must manage this state. By default, the SDK starts displaying in-app messages on every launch.

Lifecycle delegate

Implement the delegate callbacks to react to the message lifecycle.

// Called when the in-app message is about to be displayed
func willAppear(message: ZTInAppMessage)

// Called after the in-app message has been displayed
func didAppear(message: ZTInAppMessage)

// Called when the user clicks the in-app message.
// `deeplink` is non-nil when the message carries a deeplink.
func onClicked(message: ZTInAppMessage, deeplink: String?)

// Called when the user dismisses the in-app message
func onDismissed(message: ZTInAppMessage)
- (void)willAppearWithMessage:(ZTInAppMessage *)message;
- (void)didAppearWithMessage:(ZTInAppMessage *)message;
- (void)onClickedWithMessage:(ZTInAppMessage *)message
                    deeplink:(nullable NSString *)deeplink;
- (void)onDismissedWithMessage:(ZTInAppMessage *)message;

Creating an in-app message in ZMP

  1. Access the ZMP portal. Log in to ZMP.
  2. Configure the campaign.
    • Open the campaign window.
    • Select the channel Mobile InApp Push.
  3. Compose the message. Click the In-App Messaging Setup content area, then:
    • Title — provide a title.
    • Body — provide the body.
    • On-click action — choose one of:
      • Deep Link — on tap, the SDK delivers the deeplink URL through the delegate method. Your app handles internal redirection.
      • Dismiss — no action on tap.
      • Web Link — the URL opens in one of:
        • In-App Web View — opens inside the SDK in SFSafariViewController.
        • External Browser — opens in the device's default browser.
      • Email Submission — the email entered by the user in a form template is available via dataModel.inAppMessageFormData?.email.
    • In-app message image — optional.
  4. Finalize. Click Done.
  5. Activate. Activate the campaign from the portal.

In-app email collection

In-app email collection prompts unknown users (users ZMP does not yet have email for) to submit their email via an in-app form.

  • Email collection triggers only for unknown users in ZMP.
  • Known users who already have an email identifier in ZMP skip this flow entirely.

The submitted email is available on the delegate payload:

func onClicked(message: ZTInAppMessage, deeplink: String?) {
    if let email = message.inAppMessageFormData?.email {
        // Persist, forward to your backend, etc.
    }
}
- (void)onClickedWithMessage:(ZTInAppMessage *)message
                    deeplink:(nullable NSString *)deeplink {
    NSString *email = message.inAppMessageFormData.email;
    if (email != nil) {
        // Persist, forward to your backend, etc.
    }
}

Next

See also