Supported on: iOS SDK
1.0.61+ · Android SDK 1.0.33+ · Flutter SDK 1.0.3+How It Works
- You create an in-app message in the Console with content, layout, and trigger rules.
- The message definition is synced to the SDK via the config bundle.
- On every
track()call (including auto-tracked events), the SDK evaluates all active message triggers. - If conditions match, the message is presented automatically.
In-app messages are fully server-driven. You can change the message content, trigger rules, and audience without an app update.
Message Types
| Type | Description |
|---|---|
banner | Small bar at the top or bottom of the screen |
modal | Centered overlay with a dimmed background |
fullscreen | Full-screen takeover |
tooltip | Small popup anchored to a UI element |
Triggers
Messages trigger based on events and optional conditions, configured in the Console:- Event match — e.g., trigger on
workout_completed - Property conditions — e.g.,
duration >= 30 - Frequency —
once,once_per_session, orevery_time - Delay — wait N seconds after the trigger event before showing
Module Access
Module Methods
| Method | Signature | Description |
|---|---|---|
suppressDisplay | Future<void> suppressDisplay(bool suppress) | Suppress or resume in-app messages |
setDelegate | void setDelegate(AppDNAInAppMessageDelegate? delegate) | Set a delegate for message callbacks |
Suppressing Messages
Suppress messages during critical flows like checkout or onboarding to avoid interrupting the user:AppDNAInAppMessageDelegate
All 4 methods on this delegate are dispatched from the nativeMessageManager for every in-app message lifecycle event. Register your delegate via AppDNA.inAppMessages.setDelegate(...).
shouldShowMessage is a true veto. The SDK calls it BEFORE constructing the view or tracking the in_app_message_shown analytics event. If you return false, the message is suppressed entirely — no view, no analytics. The abstract class’s default implementation returns true, so hosts that don’t override this method continue to see all messages.
The 4 methods semantics:
onMessageShown(messageId, trigger)— fired after the SDK constructed the view AND emitted thein_app_message_shownanalytics event. Use for app-side telemetry or routing logic.onMessageAction(messageId, action, data)— fired when the user taps a CTA, deep-link, or custom action button. Thedatamap carries action-specific payload (URL for deep links, custom keys you set in the Console).onMessageDismissed(messageId)— fired exactly once when the message is dismissed by the user (close button, swipe, backdrop tap) or programmatically.shouldShowMessage(messageId)— veto checked before display + analytics. Default returnstrue.
Example Implementation
Rich Media
In-app messages support rich media content configured in the Console:- Lottie animations — animated hero images or backgrounds
- Video — inline video with optional autoplay and looping
- Icon buttons — CTA buttons with icon references (Lucide, SF Symbols on iOS, Material on Android, or emoji)
- Haptic feedback — triggered on message display or button taps
- Particle effects — confetti, sparkles, or other effects on message actions
- Blur backdrop — glassmorphism-style blurred background for modals
Auto-Tracked Events
| Event | Trigger |
|---|---|
in_app_message_shown | An in-app message is displayed |
in_app_message_clicked | User taps an action in the message |
in_app_message_dismissed | Message is closed |
in_app_message_received | (Android pending-message channel) A message is received before display gating |
Full Example
In-app messages are created in the Console under Engagement > In-App Messages. Design the message, set trigger rules, and publish. The SDK handles everything else.

