Obtener flows y paywalls - Kotlin Multiplatform

Lo que devuelve getFlow
✦
Flows Creados en el Flow & Paywall Builder — se renderizan de forma nativa en el dispositivo, sin WebView
✦
Paywalls del antiguo Paywall Builder Todo el contenido creado en el antiguo Paywall Builder

Después de diseñar tu flow, puedes mostrarlo en tu aplicación móvil. El primer paso es obtener el flow o paywall asociado al placement y su configuración de vista, tal como se describe a continuación.

Tip

¿Quieres ver un ejemplo real de cómo se integra el SDK de Adapty en una app móvil? Echa un vistazo a nuestras apps de ejemplo, que muestran la configuración completa, incluyendo la visualización de paywalls, la realización de compras y otras funcionalidades básicas.

Antes de empezar

Necesitas:

Obtener un flow/paywall

Si has diseñado un flow o paywall en el builder, no necesitas preocuparte por renderizarlo en el código de tu app para mostrárselo al usuario. Un flow o paywall así ya incluye tanto lo que debe mostrarse como la forma en que debe hacerlo. Aun así, necesitas obtener su ID a través del placement, su configuración de vista y, después, presentarlo en tu app.

Para garantizar un rendimiento óptimo, es fundamental obtener el flow o paywall y su configuración de vista lo antes posible, dejando tiempo suficiente para que las imágenes se descarguen antes de mostrárselas al usuario.

Para obtener un flow o paywall, usa el método getFlow:


Adapty.getFlow(
    placementId = "YOUR_PLACEMENT_ID",
    fetchPolicy = AdaptyPaywallFetchPolicy.Default,
    loadTimeout = 5.seconds
).onSuccess { flow ->
    // el flow/paywall solicitado
}.onError { error ->
    // manejar el error
}

Parámetros:

ParámetroPresenciaDescripción
placementIdobligatorioEl identificador del Placement deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard.
fetchPolicypor defecto: AdaptyPaywallFetchPolicy.Default

fetchPolicy define qué capa lee primero el SDK, no si puede usar la caché. Por defecto, el SDK consulta primero el servidor y devuelve los datos en caché si esa solicitud falla. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.

Sin embargo, si crees que tus usuarios tienen una conexión inestable, considera AdaptyPaywallFetchPolicy.ReturnCacheDataElseLoad, que invierte ese orden: lee la caché primero y solo consulta el servidor cuando no hay nada en caché. Es posible que los usuarios no obtengan los datos absolutamente más recientes, pero tendrán tiempos de carga más rápidos, independientemente de la calidad de su conexión. La caché se actualiza regularmente, por lo que es seguro usarla durante la sesión para evitar solicitudes de red.

Una tercera política, AdaptyPaywallFetchPolicy.ReturnCacheDataIfNotExpiredElseLoad(maxAgeMillis), se sitúa entre las dos: lee la caché primero mientras la copia almacenada sea más reciente que maxAgeMillis, y consulta el servidor cuando sea más antigua.

Ten en cuenta que la caché se mantiene al reiniciar la app y solo se borra al reinstalarla o mediante una limpieza manual.

El SDK de Adapty almacena los flows y paywalls localmente en dos capas: la caché de actualización periódica descrita anteriormente y los paywalls de respaldo. También usamos CDN para obtenerlos más rápido y un servidor de respaldo independiente en caso de que el CDN no esté disponible. Este sistema está diseñado para garantizar que siempre obtengas la versión más reciente y asegurar la fiabilidad incluso cuando la conexión a internet es escasa.

loadTimeoutpor defecto: 5 seg

Este valor limita el tiempo de espera de este método. Si se alcanza el tiempo de espera, se devolverán los datos en caché o el fallback local.

Ten en cuenta que en casos excepcionales este método puede superar ligeramente el tiempo de espera especificado en loadTimeout, ya que la operación puede incluir distintas solicitudes internamente.

Para Kotlin Multiplatform: puedes crear una Duration con funciones de extensión como 5.seconds, donde .seconds proviene de kotlin.time.Duration.Companion.seconds.

Parámetros de respuesta:

ParámetroDescripción
FlowUn objeto AdaptyFlow que contiene el placement, los identificadores (instanceIdentity, variationId), el nombre, las variaciones de paywall (paywalls — una lista de AdaptyFlowPaywall) y los Remote Configs (remoteConfigs — una lista con una entrada por idioma). Para obtener los productos reales y usarlos en precarga, UI personalizada o comprobaciones programáticas, llama a getPaywallProducts(flow).

Obtener la configuración de la vista

Tras obtener el flow o paywall, carga su configuración de vista y crea la vista en un solo paso con el método createFlowView. No hay ningún indicador separado que comprobar: si el placement fue diseñado en el Flow & Paywall Builder (un flow) o en el old Paywall Builder (un paywall), createFlowView devuelve la vista lista para presentarse. Si el placement es un paywall personalizado sin interfaz de Builder, createFlowView devuelve un AdaptyResult.Error — trátalo como un paywall de Remote Config.

Important

Asegúrate de publicar el flow. Un flow con ediciones sin publicar tiene el estado Dirty, y su placement sigue mostrando la última versión publicada.


AdaptyUI.createFlowView(
    flow = flow,
    loadTimeout = 5.seconds,
    preloadProducts = true
).onSuccess { view ->
    // use view
}.onError { error ->
    // the flow has no view configured, or view creation failed
}
ParámetroPresenciaDescripción
flowobligatorioUn objeto AdaptyFlow obtenido mediante Adapty.getFlow.
localeopcionalEl identificador de la localización del flow con la que se renderizará la vista — por ejemplo, en o pt-br. Si se omite, la vista se renderiza en en, o en la localización por defecto del flow cuando este no tiene en. Consulta Localizaciones y códigos de idioma.
customLayoutId

opcional

por defecto: null

SDK 4.1+

El ID personalizado de un layout definido en el Flow Builder. Pásalo para renderizar ese layout específico en lugar del que el SDK selecciona automáticamente según el tipo de dispositivo y el tamaño de pantalla. Si ningún layout coincide con el ID, el flow se carga sin configuración de vista.
loadTimeoutopcionalEste valor limita el tiempo de espera para este método. Si se alcanza el timeout, se devolverán datos en caché o el fallback local. Ten en cuenta que en casos excepcionales este método puede superar ligeramente el timeout especificado en loadTimeout, ya que la operación puede estar compuesta por diferentes solicitudes internamente. Puedes usar funciones de extensión como 5.seconds de kotlin.time.Duration.Companion.
preloadProductsopcionalEstablécelo en true para precargar productos y mejorar el rendimiento. Cuando está habilitado, los productos se cargan de antemano, reduciendo el tiempo necesario para mostrar el flow o el paywall.
productPurchaseParamsopcionalUn mapa de AdaptyProductIdentifier a AdaptyPurchaseParameters. Úsalo para configurar parámetros específicos de compra, como ofertas personalizadas o parámetros de actualización de suscripción para productos individuales en el flow o el paywall.
Note

Si usas varios idiomas, aprende cómo añadir una localización de flow.

Una vez cargado, presenta el flow o paywall.

Obtén un flow o paywall para la audiencia predeterminada y accede más rápido

Por lo general, los flows y paywalls se obtienen casi de forma instantánea, así que no necesitas preocuparte por acelerar este proceso. Sin embargo, cuando tienes muchas audiencias y placements, y tus usuarios tienen una conexión a internet débil, obtener un flow o paywall puede tardar más de lo deseable. En esas situaciones, puede que quieras mostrar un flow o paywall predeterminado para garantizar una experiencia de usuario fluida en lugar de no mostrar nada.

Para solucionar esto, puedes usar el método getFlowForDefaultAudience, que obtiene el flow o paywall del placement especificado para la audiencia All Users. Sin embargo, es fundamental entender que el enfoque recomendado es obtener el flow o paywall mediante el método getFlow, tal como se detalla en la sección Obtener flow/paywall anterior.

Warning

Por qué recomendamos usar getFlow

El método getFlowForDefaultAudience tiene algunos inconvenientes importantes:

  • Posibles problemas de compatibilidad con versiones anteriores: Si necesitas mostrar flows distintos según la versión de la app (la actual y versiones futuras), puedes encontrarte con dificultades. Tendrás que diseñar flows compatibles con la versión actual (heredada) o asumir que los usuarios con esa versión podrían tener problemas al renderizar ciertos flows.
  • Pérdida de targeting: Todos los usuarios verán el mismo flow diseñado para la audiencia All Users, lo que significa que pierdes la segmentación personalizada (incluida la basada en países, atribución de marketing o tus propios atributos personalizados).

Si estás dispuesto a aceptar estas desventajas a cambio de una obtención más rápida de flows o paywalls, utiliza el método getFlowForDefaultAudience de la siguiente manera. De lo contrario, quédate con getFlow descrito arriba.


Adapty.getFlowForDefaultAudience(
    placementId = "YOUR_PLACEMENT_ID",
    fetchPolicy = AdaptyPaywallFetchPolicy.Default,
).onSuccess { flow ->
    // the requested flow
}.onError { error ->
    // handle the error
}
ParámetroPresenciaDescripción
placementIdobligatorioEl identificador del Placement. Es el valor que especificaste al crear un placement en tu Adapty Dashboard.
fetchPolicypor defecto: AdaptyPaywallFetchPolicy.Default

fetchPolicy define qué capa lee primero el SDK, no si puede usar la caché. Por defecto, el SDK va primero al servidor y devuelve los datos en caché si esa solicitud falla. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.

Sin embargo, si crees que tus usuarios tienen una conexión a internet inestable, considera AdaptyPaywallFetchPolicy.ReturnCacheDataElseLoad, que invierte ese orden: lee primero la caché y solo va al servidor cuando no hay nada en caché. Es posible que los usuarios no reciban los datos más recientes, pero experimentarán tiempos de carga más rápidos, independientemente de lo irregular que sea su conexión. La caché se actualiza regularmente, por lo que es seguro usarla durante la sesión para evitar solicitudes de red.

Una tercera política, AdaptyPaywallFetchPolicy.ReturnCacheDataIfNotExpiredElseLoad(maxAgeMillis), se sitúa entre las dos: lee primero la caché mientras la copia en caché tenga menos de maxAgeMillis, y va al servidor cuando es más antigua.

Ten en cuenta que la caché se mantiene al reiniciar la aplicación y solo se borra cuando se reinstala la app o mediante una limpieza manual.

Personaliza los recursos

Para personalizar imágenes y vídeos en tu flow o paywall, implementa los recursos personalizados.

Las imágenes y vídeos hero tienen IDs predefinidos: hero_image y hero_video. En un bundle de recursos personalizados, seleccionas estos elementos por sus IDs y personalizas su comportamiento.

Para otras imágenes y vídeos, debes asignar un ID personalizado en el Adapty Dashboard.

Por ejemplo, puedes:

  • Mostrar una imagen o vídeo diferente a algunos usuarios.
  • Mostrar una imagen de vista previa local mientras se carga la imagen principal remota.
  • Mostrar una imagen de vista previa antes de reproducir un vídeo.

Aquí tienes un ejemplo de cómo puedes proporcionar recursos personalizados a través de un mapa:

Info

El SDK de Kotlin Multiplatform solo admite recursos locales. Para contenido remoto, debes descargar y almacenar en caché los recursos localmente antes de usarlos como recursos personalizados.

// Import generated Res class for accessing resources

viewModelScope.launch {
    // Get URIs for bundled resources using Res.getUri()
    val heroImagePath = Res.getUri("files/images/hero_image.png")
    val demoVideoPath = Res.getUri("files/videos/demo_video.mp4")

    // Or read image as byte data
    val imageByteData = Res.readBytes("files/images/avatar.png")

    // Create custom assets map
    val customAssets: Map<String, AdaptyCustomAsset> = mapOf(
        // Load image from app resources (bundled with the app)
        // Files should be placed in commonMain/composeResources/files/
        "hero_image" to AdaptyCustomAsset.localImageResource(
            path = heroImagePath
        ),

        // Or use image byte data
        "avatar" to AdaptyCustomAsset.localImageData(
            data = imageByteData
        ),

        // Load video from app resources
        "demo_video" to AdaptyCustomAsset.localVideoResource(
            path = demoVideoPath
        ),

        // Or use a video file from device storage
        "intro_video" to AdaptyCustomAsset.localVideoFile(
            path = "/path/to/local/video.mp4"
        )
    )

    // Use custom assets when creating the flow view
    AdaptyUI.createFlowView(
        flow = flow,
        customAssets = customAssets
    ).onSuccess { view ->
        // Present the flow with custom assets
        view.present()
    }.onError { error ->
        // Handle the error - the flow will fall back to default appearance
    }
}
Note

Si un recurso no se encuentra o falla al cargar, el flow o paywall volverá a su apariencia predeterminada configurada en el Builder.

Después de diseñar la parte visual de tu paywall con el antiguo Paywall Builder en el Adapty Dashboard, puedes mostrarlo en tu aplicación móvil. El primer paso en este proceso es obtener el paywall asociado al placement y su configuración de vista, tal como se describe a continuación.

Ten en cuenta que este tema se refiere a paywalls personalizados con Paywall Builder. Si estás implementando tus paywalls manualmente, consulta el tema Obtener paywalls y productos para paywalls con Remote Config en tu app móvil.

Tip

¿Quieres ver un ejemplo real de cómo se integra el SDK de Adapty en una app móvil? Echa un vistazo a nuestras apps de ejemplo, que muestran la configuración completa, incluyendo la visualización de paywalls, la realización de compras y otras funcionalidades básicas.

Antes de empezar a mostrar paywalls en tu app móvil (haz clic para expandir)
  1. Crea tus productos en el Adapty Dashboard.
  2. Crea un paywall e incorpora los productos en él en el Adapty Dashboard.
  3. Crea placements e incorpora tu paywall en ellos en el Adapty Dashboard.
  4. Instala el SDK de Adapty en tu app móvil.

Obtener un paywall diseñado con Paywall Builder

Si has diseñado un paywall con Paywall Builder, no necesitas preocuparte por renderizarlo en el código de tu app para mostrárselo al usuario. Este tipo de paywall incluye tanto lo que se muestra como la forma en que se muestra. Aun así, necesitas obtener su ID a través del placement, su configuración de vista y, después, presentarlo en tu app.

Para garantizar un rendimiento óptimo, es fundamental obtener el paywall y su configuración de vista lo antes posible, dejando tiempo suficiente para que las imágenes se descarguen antes de mostrárselas al usuario.

Para obtener un paywall, usa el método getPaywall:


Adapty.getPaywall(
    placementId = "YOUR_PLACEMENT_ID",
    locale = "en",
    fetchPolicy = AdaptyPaywallFetchPolicy.Default,
    loadTimeout = 5.seconds
).onSuccess { paywall ->
    // the requested paywall
}.onError { error ->
    // handle the error
}

Parámetros:

ParámetroPresenciaDescripción
placementIdrequeridoEl identificador del Placement deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard.
locale

opcional

predeterminado: en

El identificador de la localización del paywall. Se espera que este parámetro sea un código de idioma compuesto por uno o dos subetiquetas separadas por el carácter menos (-). La primera subetiqueta corresponde al idioma y la segunda a la región.

Ejemplo: en significa inglés, pt-br representa el portugués de Brasil.

Consulta Localizaciones y códigos de idioma para más información sobre los códigos de idioma y cómo recomendamos usarlos.

fetchPolicypredeterminado: AdaptyPaywallFetchPolicy.Default

fetchPolicy define qué capa lee primero el SDK, no si puede usar la caché. Por defecto, el SDK consulta primero el servidor y devuelve los datos en caché si esa solicitud falla. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.

Sin embargo, si crees que tus usuarios tienen una conexión a internet inestable, considera AdaptyPaywallFetchPolicy.ReturnCacheDataElseLoad, que invierte ese orden: lee primero la caché y solo va al servidor cuando no hay nada en caché. Es posible que los usuarios no obtengan los datos más recientes, pero experimentarán tiempos de carga más rápidos, independientemente de lo intermitente que sea su conexión. La caché se actualiza con regularidad, por lo que es seguro usarla durante la sesión para evitar solicitudes de red.

Una tercera política, AdaptyPaywallFetchPolicy.ReturnCacheDataIfNotExpiredElseLoad(maxAgeMillis), se sitúa entre las dos: lee primero la caché mientras la copia en caché sea más reciente que maxAgeMillis, y va al servidor cuando es más antigua.

Ten en cuenta que la caché se mantiene al reiniciar la app y solo se borra cuando se reinstala la app o mediante limpieza manual.

El SDK de Adapty almacena los paywalls localmente en dos capas: la caché de actualización regular descrita anteriormente y los paywalls de respaldo. También usamos CDN para obtener los paywalls más rápido y un servidor de respaldo independiente en caso de que el CDN no sea accesible. Este sistema está diseñado para garantizar que siempre obtengas la versión más reciente de tus paywalls, asegurando la fiabilidad incluso cuando la conexión a internet es limitada.

loadTimeoutpredeterminado: 5 seg

Este valor limita el tiempo de espera de este método. Si se alcanza el tiempo límite, se devolverán los datos en caché o el fallback local.

Ten en cuenta que en casos excepcionales este método puede superar ligeramente el tiempo especificado en loadTimeout, ya que la operación puede consistir en diferentes solicitudes internamente.

Para Kotlin Multiplatform: puedes crear un TimeInterval con funciones de extensión (como 5.seconds, donde .seconds proviene de import com.adapty.utils.seconds), o con TimeInterval.seconds(5). Para no establecer ningún límite, usa TimeInterval.INFINITE.

Parámetros de respuesta:

ParámetroDescripción
PaywallUn objeto AdaptyPaywall con una lista de IDs de productos, el identificador del paywall, el Remote Config y varias otras propiedades.

Obtener la configuración de vista de un paywall creado con Paywall Builder

Important

Asegúrate de activar el interruptor Show on device en el Paywall Builder. Si esta opción no está activada, la configuración de vista no estará disponible para recuperar.

Tras obtener el paywall, comprueba si incluye una ViewConfiguration, lo que indica que fue creado con Paywall Builder. Esto te indicará cómo mostrar el paywall. Si la ViewConfiguration está presente, trátalo como un paywall de Paywall Builder; de lo contrario, trátalo como un paywall de Remote Config.

Usa el método createPaywallView para cargar la configuración de la vista.


if (paywall.hasViewConfiguration) {
    AdaptyUI.createPaywallView(
        paywall = paywall,
        loadTimeout = 5.seconds,
        preloadProducts = true
    ).onSuccess { paywallView ->
        // use paywallView
    }.onError { error ->
        // handle the error
    }
} else {
    // use your custom logic
}
ParámetroPresenciaDescripción
paywallrequeridoUn objeto AdaptyPaywall para obtener un controlador para el paywall deseado.
loadTimeoutopcionalEste valor limita el tiempo de espera para este método. Si se alcanza el tiempo de espera, se devolverán los datos en caché o el fallback local. Ten en cuenta que en casos excepcionales este método puede agotar el tiempo de espera ligeramente después de lo especificado en loadTimeout, ya que la operación puede consistir en diferentes solicitudes internamente. Puedes usar funciones de extensión como 5.seconds de kotlin.time.Duration.Companion.
preloadProductsopcionalEstablece en true para precargar productos y mejorar el rendimiento. Cuando está activado, los productos se cargan de antemano, reduciendo el tiempo necesario para mostrar el paywall.
productPurchaseParamsopcionalUn mapa de AdaptyProductIdentifier a AdaptyPurchaseParameters. Úsalo para configurar parámetros de compra específicos, como ofertas personalizadas o parámetros de actualización de suscripción para productos individuales en el paywall.
Note

Si admites varios idiomas, añade una localización a tu paywall. Para conocer los códigos que debes usar, consulta Localizaciones y códigos de idioma.

Una vez cargado, muestra el paywall.

Obtén un paywall para la audiencia por defecto y cárgalo más rápido

Por lo general, los paywalls se cargan casi de inmediato, por lo que no necesitas preocuparte por acelerar este proceso. Sin embargo, cuando tienes numerosas audiencias y paywalls, y tus usuarios tienen una conexión a internet débil, la carga de un paywall puede tardar más de lo deseado. En esas situaciones, puede que quieras mostrar un paywall por defecto para garantizar una experiencia de usuario fluida en lugar de no mostrar ningún paywall.

Para abordar esto, puedes usar el método getPaywallForDefaultAudience, que obtiene el paywall del placement especificado para la audiencia All Users. Sin embargo, es fundamental entender que el enfoque recomendado es obtener el paywall con el método getPaywall, tal como se detalla en la sección Obtener información del paywall anterior.

Warning

Por qué recomendamos usar getPaywall

El método getPaywallForDefaultAudience tiene algunas desventajas importantes:

  • Posibles problemas de compatibilidad con versiones anteriores: Si necesitas mostrar diferentes paywalls para distintas versiones de la aplicación (actual y futuras), puedes encontrarte con dificultades. Tendrás que diseñar paywalls compatibles con la versión actual (heredada) o asumir que los usuarios con esa versión pueden tener problemas con paywalls que no se rendericen correctamente.
  • Pérdida de targeting: Todos los usuarios verán el mismo paywall diseñado para la audiencia All Users, lo que significa que pierdes la segmentación personalizada (incluyendo por países, atribución de marketing o tus propios atributos personalizados).

Si estás dispuesto a aceptar estos inconvenientes para beneficiarte de una obtención más rápida del paywall, utiliza el método getPaywallForDefaultAudience como se indica a continuación. De lo contrario, sigue usando getPaywall descrito anteriormente.


Adapty.getPaywallForDefaultAudience(
    placementId = "YOUR_PLACEMENT_ID",
    locale = "en",
    fetchPolicy = AdaptyPaywallFetchPolicy.Default,
).onSuccess { paywall ->
    // the requested paywall
}.onError { error ->
    // handle the error
}
ParámetroPresenciaDescripción
placementIdrequeridoEl identificador del Placement. Es el valor que especificaste al crear un placement en tu Adapty Dashboard.
locale

opcional

predeterminado: en

El identificador de la localización del paywall. Se espera que este parámetro sea un código de idioma compuesto por una o más subtags separadas por el carácter menos (-). La primera subtag corresponde al idioma y la segunda a la región.

Ejemplo: en significa inglés, pt-br representa el portugués de Brasil.

Consulta Localizaciones y códigos de idioma para más información sobre los códigos de idioma y cómo recomendamos usarlos.

fetchPolicypredeterminado: AdaptyPaywallFetchPolicy.Default

fetchPolicy define qué capa lee primero el SDK, no si puede usar la caché. Por defecto, el SDK va primero al servidor y devuelve los datos en caché si esa solicitud falla. Recomendamos esta opción porque garantiza que tus usuarios siempre reciban los datos más actualizados.

Sin embargo, si crees que tus usuarios tienen una conexión a internet inestable, considera AdaptyPaywallFetchPolicy.ReturnCacheDataElseLoad, que invierte ese orden: lee primero la caché y va al servidor solo cuando no hay nada en caché. Es posible que los usuarios no obtengan los datos más recientes, pero experimentarán tiempos de carga más rápidos, independientemente de la calidad de su conexión. La caché se actualiza con regularidad, por lo que es seguro usarla durante la sesión para evitar solicitudes de red.

Una tercera política, AdaptyPaywallFetchPolicy.ReturnCacheDataIfNotExpiredElseLoad(maxAgeMillis), se sitúa entre las dos: lee primero la caché mientras la copia en caché sea más reciente que maxAgeMillis, y va al servidor una vez que sea más antigua.

Ten en cuenta que la caché se mantiene intacta al reiniciar la app y solo se borra cuando se reinstala la app o mediante una limpieza manual.

Personalizar recursos

Para personalizar las imágenes y vídeos de tu paywall, implementa los recursos personalizados.

Las imágenes y vídeos hero tienen IDs predefinidos: hero_image y hero_video. En un bundle de recursos personalizado, apuntas a estos elementos por sus IDs y personalizas su comportamiento.

Para otras imágenes y vídeos, necesitas establecer un ID personalizado en el Adapty Dashboard.

Por ejemplo, puedes:

  • Mostrar una imagen o vídeo diferente a algunos usuarios.
  • Mostrar una imagen de previsualización local mientras se carga una imagen principal remota.
  • Mostrar una imagen de previsualización antes de reproducir un vídeo.
Important

Para usar esta función, actualiza el SDK de Adapty a la versión 3.7.0 o superior.

A continuación se muestra un ejemplo de cómo puedes proporcionar recursos personalizados mediante un mapa:

Info

El SDK de Kotlin Multiplatform solo admite recursos locales. Para contenido remoto, debes descargar y almacenar en caché los recursos localmente antes de usarlos como recursos personalizados.

// Import generated Res class for accessing resources

viewModelScope.launch {
    // Get URIs for bundled resources using Res.getUri()
    val heroImagePath = Res.getUri("files/images/hero_image.png")
    val demoVideoPath = Res.getUri("files/videos/demo_video.mp4")

    // Or read image as byte data
    val imageByteData = Res.readBytes("files/images/avatar.png")

    // Create custom assets map
    val customAssets: Map<String, AdaptyCustomAsset> = mapOf(
        // Load image from app resources (bundled with the app)
        // Files should be placed in commonMain/composeResources/files/
        "hero_image" to AdaptyCustomAsset.localImageResource(
            path = heroImagePath
        ),

        // Or use image byte data
        "avatar" to AdaptyCustomAsset.localImageData(
            data = imageByteData
        ),

        // Load video from app resources
        "demo_video" to AdaptyCustomAsset.localVideoResource(
            path = demoVideoPath
        ),

        // Or use a video file from device storage
        "intro_video" to AdaptyCustomAsset.localVideoFile(
            path = "/path/to/local/video.mp4"
        ),

        // Apply custom brand colors
        "brand_primary" to AdaptyCustomAsset.color(
            colorHex = "#FF6B35"
        ),

        // Create gradient background
        "card_gradient" to AdaptyCustomAsset.linearGradient(
            colors = listOf("#1E3A8A", "#3B82F6", "#60A5FA"),
            stops = listOf(0.0f, 0.5f, 1.0f)
        )
    )

    // Use custom assets when creating paywall view
    AdaptyUI.createPaywallView(
        paywall = paywall,
        customAssets = customAssets
    ).onSuccess { paywallView ->
        // Present the paywall with custom assets
        paywallView.present()
    }.onError { error ->
        // Handle the error - paywall will fall back to default appearance
    }
}
Note

Si un asset no se encuentra o no se carga correctamente, el paywall volverá a su apariencia predeterminada configurada en el Paywall Builder.