Fetch and Display Content Cards
This tutorial explains how to fetch and display content cards in your application.
Pre-requisites
Integrate and register AEPMessaging extension in your app.
Fetch Content Cards
To fetch the content cards for the surfaces configured in Adobe Journey Optimizer campaigns, call the updatePropositionsForSurfaces API. You should batch requests for multiple surfaces in a single API call when possible. The returned content cards are cached in-memory by the Messaging extension and persist through the application's lifecycle.
data-slots=heading, code
data-repeat=1
data-languages=Kotlin
Kotlin
val surfaces = mutableListOf<Surface>()
val surface = Surface("homepage")
Messaging.updatePropositionsForSurfaces(surfaces)
Retrieve Content Cards
To retrieve the content cards for a specific surface, call getContentCardUIFlow. This API returns a flow of Result containing AepUI objects representing content cards for which the user is qualified.
AepUI objects are created only for content cards with templates recognized by the Messaging extension. The flow of AepUI objects may contain multiple content card template types: SmallImageUI, LargeImageUI, and ImageOnlyUI.
data-slots=heading, code
data-repeat=1
data-languages=Kotlin
Kotlin
// create a view model or reuse existing one to hold the aepUIList
class AepContentCardViewModel(private val contentCardUIProvider: ContentCardUIProvider) : ViewModel() {
// State to hold AepUI list
private val _aepUIList = MutableStateFlow<List<AepUI<*, *>>>(emptyList())
val aepUIList: StateFlow<List<AepUI<*, *>>> = _aepUIList.asStateFlow()
// Obtain the flow outside of a coroutine — no suspend needed
val contentCardFlow = contentCardUIProvider.getContentCardUIFlow()
init {
// Collect the flow; content is fetched lazily on first collection
viewModelScope.launch {
contentCardFlow.collect { result ->
result.onSuccess {
aepUi -> _aepUIList.value = aepUi
}
result.onFailure { throwable ->
// handle onFailure if needed
}
}
}
}
// Function to refresh the aepUIList from the ContentCardUIProvider
fun refreshContent() {
viewModelScope.launch {
contentCardUIProvider.refreshContent()
}
}
}
data-variant=info
data-slots=text
getContentCardUIFlow API. Client-side rules are defined in the Adobe Journey Optimizer campaign.Display Content Cards
The Content Card user interface is implemented using Jetpack Compose, which is the recommended toolkit for Android development. To display content cards in your app, pass the AepUI objects returned by the getContentCardUIFlow API to the appropriate Content Card composable. The currently supported composables are:
SmallImageCardcomposable forSmallImageUILargeImageCardcomposable forLargeImageUIImageOnlyCardcomposable forImageOnlyUI
Display Content Cards in Compose UI application
Below is an example of how to display content cards in a Compose UI application:
data-slots=heading, code
data-repeat=1
data-languages=Kotlin
Kotlin
@Composable
private fun AepContentCardList(viewModel: AepContentCardViewModel) {
val aepUiList by viewModel.aepUIList.collectAsStateWithLifecycle()
val provider = viewModel.contentCardUIProvider
LazyRow {
items(aepUiList) { aepUI ->
when (aepUI) {
is SmallImageUI -> {
val state = aepUI.getState()
if (!state.dismissed) {
SmallImageCard(
ui = aepUI,
style = SmallImageUIStyle.Builder().build(),
observer = ContentCardEventObserver(contentCardCallback, provider)
)
}
}
is LargeImageUI -> {
val state = aepUI.getState()
if (!state.dismissed) {
LargeImageCard(
ui = aepUI,
style = LargeImageUIStyle.Builder().build(),
observer = ContentCardEventObserver(contentCardCallback, provider)
)
}
}
is ImageOnlyUI -> {
val state = aepUI.getState()
if (!state.dismissed) {
ImageOnlyCard(
ui = aepUI,
style = ImageOnlyUIStyle.Builder().build(),
observer = ContentCardEventObserver(contentCardCallback, provider)
)
}
}
}
}
}
}
Refer to this TestApp for a complete example of how to display, customize and listen to UI events from content cards in a Compose UI application.
Retrieve ContentCardSchemaData from the Messaging extension
You may retrieve the ContentCardSchemaData for a Content Card with the template ID using the ContentCardMapper:
data-slots=heading, code
data-repeat=1
data-languages=Kotlin
Kotlin
private fun AepContentCardList(viewModel: AepContentCardViewModel) {
// Collect the state from ViewModel
val aepUiList by viewModel.aepUIList.collectAsStateWithLifecycle()
// Get the ContentCardSchemaData for the AepUI list if needed
val contentCardSchemaDataList = aepUiList.map {
when (it) {
is SmallImageUI ->
ContentCardMapper.Companion.instance.getContentCardSchemaData(it.getTemplate().id)
else -> null
}
}
}