In dynamic apps, AJO in-app messages can sometimes render before the SDK has the latest profile data, causing users to see messages they no longer qualify for—or miss messages they should receive. Manually refreshing IAM propositions helps keep message eligibility accurate and aligned with the user’s current state.
How do in-app messages use default surfaces?
Even though IAMs are configured inside AJO’s In-App Messaging UI, the delivery mechanism is the same as Code-Based Experiences:
-
IAMs are delivered as propositions
-
Propositions are fetched via surfaces
-
IAM Surfaces follow the mobileapp:// appID pattern
This is why refreshing a default surface refreshes all IAM eligibility—without needing to reconfigure your IAMs.
When you should manually refresh IAMs
You should refresh IAMs when:
-
The customer’s profile or segment status changes inside the app session
-
User just made a qualifying purchase
-
The app expects IAM eligibility to change immediately
-
You want to avoid the default retry window and force an immediate sync
-
The SDK has older cached propositions and needs a refresh
This is especially critical in scenarios where IAMs keep showing after a user makes a purchase or exits a journey.
How to trigger an IAM refresh
Define default Surface name for IAM: This must match the default mobile surface pattern:
-
This is the reserved in-app messaging surface for every app
-
An In-app channel needs to be setup in AJO
-
It is automatically recognized by the Mobile SDK
-
It must match your app’s registered app ID/bundle ID
let surface1 = Surface(path: "bundleIdentifier") //Dedicated surface for IAM
let surface2 = Surface(path: "myViewAttributes") //Any other Code based experience surface
Use one of the three methods as per the use case (Fetch fresh IAM propositions)
1. Using refreshInAppMessages() API
By default, the SDK will automatically fetch in-app message definitions from the remote at the time the Messaging extension is registered. This generally happens once per app lifecycle. Some use cases may require the client to request an update from the remote more frequently. Calling the following API will force the Messaging extension to get an updated definition of messages from the remote configuration.
This is easy for customers that only have in-app messaging. This is an asynchronous method that does not have a callback.
Let me explain in simplest terms. if you called,
Messaging.refreshInAppMessages()
MobileCore.track(action: "myAction", data: nil)
Then the track event can be processed before the messages finish being refreshed from the remote configuration. So, it would miss any potential messages for which the user should have qualified (being async).
2. Using updatePropositionsForSurfaces([iamSurface]) API
This method is used for updating all kinds of propositions – in-app messages, content cards, and code-based experiences.
Like Method 1, this is also an asynchronous method.
Explaining with code below:
let surface1 = Surface(path: "bundleIdentifier") //Dedicated surface for IAM
let surface2 = Surface(path: "myViewAttributes") //Any other Code based experience surface
Messaging.updatePropositionsForSurfaces([surface1, surface2])
This forces AJO to send fresh eligibility based on the latest profile and segment - membership for IAM as well as the CBE, for both.
3. Using updatePropositionsForSurfacesWithCompletionHandler API
This is an asynchronous method which waits for the IAMs to be fetched and processed before executing the code in the callback. But this method is only available in the newer AEPMessaging packages.
This API allows you to pass a callback to check for successful completion of all the IAM fetches. If provided, completion will be called on the Messaging extension background thread once the response has been fully processed. true will be passed to the completion method if a network response was returned and successfully processed. a false will be passed otherwise.
This method also serves a special use case of Push to in app message – meaning,
A designated in-app message is shown to an end user when they interact with a push notification to open the app
A simple code example is given below:
let iamSurface = Surface()
Messaging.updatePropositionsForSurfaces([iamSurface]) { success in
if success {
// handle success scenario - e.g. sendEvent
let myEvent = ExperienceEvent(xdm: ["key": "value"]) //send data
Edge.sendEvent(experienceEvent: myEvent)
} else {
// Handle error scenario
}
}
No custom event is required just to refresh IAMs.
However, if you need profile values updated on Edge before refreshing propositions, you can send an XDM event first:
"eventType": "profileStateChange",//this could be anything
"user": ["lifecycleStatus": "purchased"]//optional parameters
]
Edge.sendEvent(xdm: xdmData)
Messaging.updatePropositions(forSurfaces: [surface])
This guarantees correct sequencing:
-
update profile →
-
fetch propositions →
-
display accurate IAMs
Complete example: Updating IAM after purchase
import UIKit
import AEPCore
import AEPEdge
import AEPMessaging
class AppDelegate: UIResponder, UIApplicationDelegate {
func handlePurchaseCompleted() {
let surface = Surface();
//step 1: Send Event to update Profile (optional but recommended)
Edge.sendEvent(xdm: [
"eventType": "commerce.purchases",
"commerce": ["purchases"["value": 1]]
])
//step 2: Immediately refresh IAM eligibility
Messaging.updatePropositions(for: [surface]) { success ->
if (success) {
// Trigger IAM on launch
Edge.sendEvent()..
} else {
// handle error scenario
}
}
}
Final thoughts
In-App Messages are powerful because they’re real-time and contextual—but only if they’re synced with the latest customer state. Using updatePropositions gives you precise control over IAM eligibility whenever profile changes occur inside the app.
This workflow is not a replacement for your IAM configuration—it simply ensures you always fetch the most accurate version of it.
If you need Android or React Native code examples, comment below and I will send you those snippets. Thanks!
Helpful Adobe documentation links
These links provide the official API references behind the approach:
Mobile Core – updatePropositions API
Messaging Extension – surfaces & propositions