Obtener flows y paywalls - iOS
getFlow retrieves Tras diseñar tu flow o tu paywall con el Paywall Builder, puedes mostrarlo en tu aplicación móvil. El primer paso es obtener el flow o el paywall asociado al placement y su configuración de vista, tal como se describe a continuación.
¿Quieres ver un ejemplo real de cómo se integra el SDK de Adapty en una aplicación móvil? Consulta 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
- Crea tus productos en el Adapty Dashboard.
- Crea un flow/paywall e incorpora productos en él en el Adapty Dashboard.
- Crea placements e incorpora tu flow/paywall en ellos en el Adapty Dashboard.
- Instala el SDK de Adapty en tu app móvil.
Obtener el flow/paywall
Si has diseñado un flow o paywall con el Flow Builder o el Paywall Builder, no tienes que preocuparte por renderizarlo en el código de tu app para mostrárselo al usuario. Ese flow o paywall ya incluye tanto lo que se debe mostrar como la forma en que debe mostrarse. Aun así, necesitas obtener su ID a través del placement, su configuración de vista y luego 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, dando 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:
Parámetros:
| Parámetro | Presencia | Descripción |
|---|---|---|
| placementId | obligatorio | El identificador del Placement deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard. |
| fetchPolicy | por defecto: .reloadRevalidatingCacheData | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché en caso de fallo. 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 usar Ten en cuenta que la caché permanece intacta al reiniciar la app y solo se borra cuando se reinstala la app o mediante una limpieza manual. El SDK de Adapty almacena los paywalls localmente en dos capas: la caché actualizada periódicamente que se describe arriba 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 escasa. |
| loadTimeout | por defecto: 5 seg | Este valor limita el tiempo de espera para 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 |
| Parámetros de respuesta: |
| Parámetro | Descripción |
|---|---|
| Flow | Un objeto AdaptyFlow que contiene el placement, identificadores (id, variationId), nombre, Remote Configs y un indicador hasViewConfiguration que señala si el flow incluye una configuración de vista. Para obtener los productos reales con fines de precarga, UI personalizada o comprobaciones programáticas, llama a getPaywallProducts(flow:). |
Obtener la configuración de vista
Después de obtener el flow o el paywall, comprueba si incluye una configuración de vista mediante flow.hasViewConfiguration. Este flag distingue cómo se diseñó el placement en el Adapty Dashboard:
true— el placement fue diseñado en el Flow Builder (un flow) o en el Paywall Builder (un paywall). Adapty renderiza la interfaz por ti. Continúa con los pasos a continuación para obtener la configuración de vista y mostrar el flow o el paywall.false— el placement es un paywall personalizado sin interfaz del Builder. Usa el métodogetFlowConfigurationpara cargar la configuración de la vista.
guard flow.hasViewConfiguration else {
// handle as remote config paywall
return
}
let flowConfiguration = try await AdaptyUI.getFlowConfiguration(forFlow: flow)Parámetros:
| Parámetro | Presencia | Descripción |
|---|---|---|
| forFlow | obligatorio | Un objeto AdaptyFlow obtenido mediante Adapty.getFlow. |
| locale | opcional por defecto: | El identificador de la localización del paywall. Se espera como un código de idioma con una o dos subetiquetas separadas por - (p. ej., en, pt-br). Consulta Localizaciones y códigos de idioma. |
| loadTimeout | por defecto: 5 seg | Este valor limita el tiempo de espera para este método. Si se alcanza el límite, se devolverán los datos en caché o el fallback local. Ten en cuenta que en casos poco frecuentes este método puede superar ligeramente el tiempo indicado en loadTimeout, ya que la operación puede constar de distintas solicitudes internamente. |
| products | opcional | Proporciona un array de objetos AdaptyPaywallProduct para optimizar el momento en que se muestran los productos en pantalla. Si se pasa nil, AdaptyUI obtendrá automáticamente los productos necesarios. |
| systemRequestsHandler | opcional | Un objeto que implementa AdaptySystemRequestsHandler y gestiona las solicitudes de permisos del sistema y valoraciones activadas por acciones del flow. Solo es necesario si tu flow incluye este tipo de acciones. |
| assetsResolver | opcional | Un diccionario [String: AdaptyCustomAsset] que sobreescribe imágenes y vídeos en el flow/paywall. Consulta Personalizar assets. |
| timerResolver | opcional | Un objeto que implementa AdaptyTimerResolver y proporciona fechas de finalización para los temporizadores definidos por el desarrollador. Consulta Configurar temporizadores definidos por el desarrollador. |
| Una vez cargado, presenta el flow/paywall. |
Obtén un flow o paywall para la audiencia predeterminada y cárgalo más rápido
Por lo general, los flows y paywalls se obtienen casi al instante, por lo que no es necesario preocuparse por acelerar este proceso. Sin embargo, si tienes muchas audiencias y placements, y tus usuarios tienen una conexión a internet lenta, obtener un flow o paywall puede tardar más de lo que desearías. En esos casos, 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 con el método getFlow, tal como se detalla en la sección Obtener información del paywall anterior.
Por qué recomendamos usar getFlow
El método getFlowForDefaultAudience tiene algunos inconvenientes importantes:
- Posibles problemas de compatibilidad con versiones anteriores: Si necesitas mostrar distintos paywalls para diferentes versiones de la app (la actual y las futuras), puedes encontrarte con dificultades. Tendrás que diseñar paywalls compatibles con la versión actual (legacy) o asumir que los usuarios de esa versión podrían tener problemas con paywalls que no se renderizan 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ís, atribución de marketing o tus propios atributos personalizados).
Si estás dispuesto a aceptar estas limitaciones a cambio de una obtención más rápida del flow o del paywall, usa el método
getFlowForDefaultAudiencede la siguiente manera. De lo contrario, quédate congetFlowdescrito anteriormente.
Adapty.getFlowForDefaultAudience(placementId: "YOUR_PLACEMENT_ID") { result in
switch result {
case let .success(flow):
// the requested flow
case let .failure(error):
// handle the error
}
}
| Parámetro | Presencia | Descripción |
|---|---|---|
| placementId | obligatorio | El identificador del Placement. Es el valor que especificaste al crear un placement en tu Adapty Dashboard. |
| fetchPolicy | por defecto: .reloadRevalidatingCacheData | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché en caso de fallo. 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 usar Ten en cuenta que la caché permanece intacta al reiniciar la app y solo se borra cuando se reinstala la app o mediante una limpieza manual. |
Personalizar recursos
Para personalizar imágenes y vídeos en tu paywall/flow, implementa los recursos personalizados.
Las imágenes y vídeos destacados tienen IDs predefinidos: hero_image y hero_video. En un bundle de recursos personalizados, 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:
- Muestra una imagen o vídeo diferente a algunos usuarios.
- Muestra una imagen de vista previa local mientras se carga la imagen principal remota.
- Muestra una imagen de vista previa antes de reproducir un vídeo.
- Indica la resolución en píxeles del vídeo para que el reproductor reserve espacio en el layout (relación de aspecto =
width / height) antes de que cargue el vídeo. Pasanilpara omitirlo.
A continuación se muestra un ejemplo de cómo puedes proporcionar assets personalizados mediante un diccionario sencillo:
let customAssets: [String: AdaptyCustomAsset] = [
// Show a local image using a custom ID
"custom_image": .image(
.uiImage(value: UIImage(named: "image_name")!)
),
// Show a local preview image while a remote main image is loading
"hero_image": .image(
.remote(
url: URL(string: "https://example.com/image.jpg")!,
preview: UIImage(named: "preview_image")
)
),
// Show a local video with a preview image and a known resolution
"hero_video": .video(
.file(
url: Bundle.main.url(forResource: "custom_video", withExtension: "mp4")!,
preview: .uiImage(value: UIImage(named: "video_preview")!),
resolution: CGSize(width: 1080, height: 1920)
)
),
]
let flowConfig = try await AdaptyUI.getFlowConfiguration(
forFlow: flow,
assetsResolver: customAssets
)Si no se encuentra un asset, el paywall/flow volverá a su apariencia predeterminada.
Configurar temporizadores definidos por el desarrollador
Para usar temporizadores personalizados en tu app, crea un objeto que implemente el protocolo AdaptyTimerResolver. Este objeto define cómo debe renderizarse cada temporizador personalizado. Si lo prefieres, puedes usar directamente un diccionario [String: Date], ya que ya cumple con este protocolo. Aquí tienes un ejemplo:
@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
func timerEndAtDate(for timerId: String) -> Date {
switch timerId {
case "CUSTOM_TIMER_6H":
Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
case "CUSTOM_TIMER_NY":
Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
default:
Date(timeIntervalSinceNow: 3600.0) // 1 hour
}
}
}En este ejemplo, CUSTOM_TIMER_NY y CUSTOM_TIMER_6H son los Timer ID de los temporizadores definidos por el desarrollador que configuraste en el Adapty Dashboard. El timerResolver garantiza que tu app actualice dinámicamente cada temporizador con el valor correcto. Por ejemplo:
CUSTOM_TIMER_NY: El tiempo restante hasta que finalice el temporizador, como el Año Nuevo.CUSTOM_TIMER_6H: El tiempo restante en un período de 6 horas que comenzó cuando el usuario abrió el paywall.
Después de diseñar la parte visual de tu paywall con el Paywall Builder en el Adapty Dashboard, puedes mostrarlo en tu app móvil. El primer paso 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 hace referencia a paywalls personalizados con el Paywall Builder. Si implementas tus paywalls manualmente, consulta Obtener paywalls y productos para paywalls con Remote Config.
Antes de empezar a mostrar paywalls en tu aplicación móvil, asegúrate de que ya has:
Antes de empezar a mostrar paywalls en tu aplicación móvil
- Crea tus productos en el Adapty Dashboard.
- Crea un paywall e incorpora los productos en él en el Adapty Dashboard.
- Crea placements e incorpora tu paywall en ellos en el Adapty Dashboard.
- Instala el SDK de Adapty en tu aplicación móvil.
Obtén el paywall diseñado con Paywall Builder
Si has diseñado un paywall con el 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 qué mostrar como cómo mostrarlo. Aun así, necesitas obtener su ID a través del placement, su configuración de vista, y luego 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:
Parámetros:
| Parámetro | Presencia | Descripción |
|---|---|---|
| placementId | obligatorio | El identificador del Placement deseado. Es el valor que especificaste al crear un placement en el Adapty Dashboard. |
| locale | opcional por defecto: | 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: Consulta Localizaciones y códigos de idioma para más información sobre los códigos de idioma y cómo recomendamos utilizarlos. |
| fetchPolicy | por defecto: .reloadRevalidatingCacheData | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché en caso de fallo. 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 usar Ten en cuenta que la caché permanece intacta al reiniciar la app y solo se borra cuando se reinstala la app o mediante una limpieza manual. El SDK de Adapty almacena los paywalls localmente en dos capas: la caché de actualización periódica 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 y que el servicio sea fiable incluso cuando la conexión a internet sea escasa. |
| loadTimeout | por defecto: 5 seg | Este valor limita el tiempo de espera de este método. Si se alcanza el 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 |
| Parámetros de respuesta: |
| Parámetro | Descripción |
|---|---|
| Paywall | Un 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
Asegúrate de activar el botón Show on device en el Paywall Builder. Si esta opción no está activada, la configuración de vista no estará disponible para recuperar.
Después de obtener el paywall, comprueba si incluye una configuración de vista, lo que indica que fue creado con Paywall Builder. Esto te indicará cómo mostrar el paywall. Si la configuración de vista está presente, trátalo como un paywall de Paywall Builder; si no, trátalo como un paywall de Remote Config.
Usa el método getPaywallConfiguration para cargar la configuración de la vista.
guard paywall.hasViewConfiguration else {
// use your custom logic
return
}
do {
let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(
forPaywall: paywall,
products: products
)
// use loaded configuration
} catch {
// handle the error
}Parámetros:
| Parámetro | Presencia | Descripción |
|---|---|---|
| paywall | obligatorio | Un objeto AdaptyPaywall para obtener un controlador del paywall deseado. |
| loadTimeout | por defecto: 5 seg | Este valor limita el tiempo de espera para 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 agotar el tiempo ligeramente después de lo especificado en loadTimeout, ya que la operación puede constar de distintas solicitudes internamente. |
| products | opcional | Proporciona un array de objetos AdaptyPaywallProduct para optimizar el tiempo de visualización de los productos en pantalla. Si se pasa nil, AdaptyUI obtendrá automáticamente los productos necesarios. |
Si estás usando varios idiomas, aprende cómo añadir una localización en el Paywall Builder y cómo usar los códigos de idioma correctamente aquí.
Una vez cargado, muestra el paywall.
Obtén un paywall para la audiencia predeterminada y acelera la carga
Normalmente, los paywalls se obtienen casi de forma instantánea, así que no necesitas preocuparte por optimizar este proceso. Sin embargo, cuando tienes muchas 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 deseable. En esos casos, puede que quieras mostrar un paywall predeterminado para garantizar una experiencia fluida en lugar de no mostrar ninguno.
Para solucionar esto, puedes usar el método getPaywallForDefaultAudience, que obtiene el paywall del placement indicado para la audiencia All Users. Sin embargo, es importante 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.
Por qué recomendamos usar getPaywall
El método getPaywallForDefaultAudience tiene algunos inconvenientes importantes:
- Posibles problemas de compatibilidad con versiones anteriores: Si necesitas mostrar paywalls diferentes para distintas versiones de la app (la actual y las futuras), puede que te encuentres con dificultades. Tendrás que diseñar paywalls que sean compatibles con la versión actual (legacy), o asumir que los usuarios con esa versión podrían tener problemas con paywalls que no se renderizan 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 (incluida la basada en 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, usa el método
getPaywallForDefaultAudiencede la siguiente manera. De lo contrario, quédate congetPaywalldescrito anteriormente.
Adapty.getPaywallForDefaultAudience(placementId: "YOUR_PLACEMENT_ID", locale: "en") { result in
switch result {
case let .success(paywall):
// the requested paywall
case let .failure(error):
// handle the error
}
}El método getPaywallForDefaultAudience está disponible a partir de la versión 2.11.2 del SDK de iOS.
| Parámetro | Presencia | Descripción |
|---|---|---|
| placementId | requerido | El identificador del Placement. Es el valor que especificaste al crear un placement en tu Adapty Dashboard. |
| locale | opcional valor por defecto: | 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 subetiquetas separadas por el carácter menos (-). La primera subetiqueta corresponde al idioma y la segunda a la región. Ejemplo: Consulta Localizaciones y códigos de idioma para más información sobre los códigos de idioma y cómo recomendamos usarlos. |
| fetchPolicy | valor por defecto: .reloadRevalidatingCacheData | Por defecto, el SDK intentará cargar los datos desde el servidor y devolverá los datos en caché en caso de fallo. 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 usar Ten en cuenta que la caché permanece intacta al reiniciar la app y solo se borra cuando se reinstala la app o mediante una limpieza manual. |
Personalizar recursos
Para personalizar imágenes y vídeos en tu paywall, implementa 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, 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 vista previa local mientras se carga la imagen principal remota.
- Mostrar una imagen de vista previa antes de reproducir un vídeo.
Para usar esta función, actualiza el SDK de Adapty para iOS a la versión 3.7.0 o superior.
Aquí tienes un ejemplo de cómo puedes proporcionar assets personalizados mediante un diccionario sencillo:
let customAssets: [String: AdaptyCustomAsset] = [
// Show a local image using a custom ID
"custom_image": .image(
.uiImage(value: UIImage(named: "image_name")!)
),
// Show a local preview image while a remote main image is loading
"hero_image": .image(
.remote(
url: URL(string: "https://example.com/image.jpg")!,
preview: UIImage(named: "preview_image")
)
),
// Show a local video with a preview image
"hero_video": .video(
.file(
url: Bundle.main.url(forResource: "custom_video", withExtension: "mp4")!,
preview: .uiImage(value: UIImage(named: "video_preview")!)
)
),
]
let paywallConfig = try await AdaptyUI.getPaywallConfiguration(
forPaywall: paywall,
assetsResolver: customAssets
)Si no se encuentra un asset, el paywall volverá a su apariencia predeterminada.
Configurar temporizadores definidos por el desarrollador
Para usar temporizadores personalizados en tu app, crea un objeto que implemente el protocolo AdaptyTimerResolver. Este objeto define cómo se debe renderizar cada temporizador personalizado. Si lo prefieres, puedes usar directamente un diccionario [String: Date], ya que ya es compatible con este protocolo. Aquí tienes un ejemplo:
@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
func timerEndAtDate(for timerId: String) -> Date {
switch timerId {
case "CUSTOM_TIMER_6H":
Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
case "CUSTOM_TIMER_NY":
Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
default:
Date(timeIntervalSinceNow: 3600.0) // 1 hour
}
}
}En este ejemplo, CUSTOM_TIMER_NY y CUSTOM_TIMER_6H son los Timer IDs de los temporizadores definidos por el desarrollador que configuraste en el Adapty Dashboard. El timerResolver garantiza que tu app actualice dinámicamente cada temporizador con el valor correcto. Por ejemplo:
CUSTOM_TIMER_NY: El tiempo restante hasta el fin del temporizador, como el día de Año Nuevo.CUSTOM_TIMER_6H: El tiempo que queda en un período de 6 horas que empezó cuando el usuario abrió el paywall.