Skip to content

Commit f40c2f6

Browse files
chore: update translations
1 parent 7e09816 commit f40c2f6

16 files changed

Lines changed: 585 additions & 4 deletions
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"fileHash":"sha256:0b2589500dceea0ad7fe73cbd92a611b1401c9f4085fe1a953676b6f3de7d9b1","sections":{"preamble-p0a8dc688":{"contentHash":"sha256:0a8dc688f915d9a06090754a8b274772802f3f1e9450475f7c3ee46255e7369a","proseHash":"sha256:0a8dc688f915d9a06090754a8b274772802f3f1e9450475f7c3ee46255e7369a","translation":"---\ntitle: \"Mostrar un paywall orientado a Apple Ads en el primer lanzamiento\"\ndescription: \"Espera la atribución de Apple Ads antes de solicitar el paywall en iOS usando AdaptyProfile.appliedAttributionSources.\"\nmetadataTitle: \"Mostrar un paywall orientado a Apple Ads en el primer lanzamiento | iOS SDK | Documentación de Adapty\"\n---"},"preamble-pd112acd0":{"contentHash":"sha256:d112acd044381ffa0c15e704df6f8d2144c7acc0ebdcee2b0325aa5a1e3af70f","proseHash":"sha256:d112acd044381ffa0c15e704df6f8d2144c7acc0ebdcee2b0325aa5a1e3af70f","translation":"Apple Ads (AA) llega de forma asíncrona después de `Adapty.activate()`. Si llamas a `getPaywall` demasiado pronto, la atribución aún no habrá llegado y Adapty resolverá el placement contra la audiencia predeterminada, saltándose tus paywalls segmentados por ASA. `AdaptyProfile.appliedAttributionSources` permite que la app detecte cuándo se ha aplicado la atribución de ASA al perfil, de modo que la solicitud del paywall pueda esperar hasta que la segmentación de ASA se resuelva correctamente."},"h2-before-you-start":{"contentHash":"sha256:0ca0c672a9d9735399f379602a4d82fcffa24fd73ea3f441951173ccf9894f64","proseHash":"sha256:0ca0c672a9d9735399f379602a4d82fcffa24fd73ea3f441951173ccf9894f64","translation":"## Antes de empezar \\{#before-you-start\\}\n\nNecesitas:\n- Adapty iOS SDK **3.17.1** o posterior.\n- Apple Ads configurado para la app en Adapty. Consulta [Apple Ads](apple-search-ads)."},"h2-how-it-works-p14797c68":{"contentHash":"sha256:14797c68b9b623b738f3c716e00957a547c4f4d8be176834285492cc5cbec8e8","proseHash":"sha256:14797c68b9b623b738f3c716e00957a547c4f4d8be176834285492cc5cbec8e8","translation":"## Cómo funciona \\{#how-it-works\\}\n\nTras ejecutar `Adapty.activate()`, el SDK solicita en segundo plano la atribución de Apple Ads a Apple y reenvía el resultado al backend de Adapty. Cuando ASA se convierte en la fuente de atribución activa del perfil, el SDK entrega un `AdaptyProfile` actualizado cuyo array `appliedAttributionSources` contiene `.appleAds`.\n\nUn array vacío puede significar cualquiera de estas cosas:\n\n- La atribución de Apple Ads aún no se ha procesado para este perfil.\n- No ha llegado ninguna atribución."},"h2-how-it-works-p14c20c52":{"contentHash":"sha256:14c20c522ddb61e8a899e098ddd85fca1c32f8801f9bb9462e897d224ad209f2","proseHash":"sha256:14c20c522ddb61e8a899e098ddd85fca1c32f8801f9bb9462e897d224ad209f2","translation":"Incluso con un array vacío, `getPaywall` sigue siendo seguro de llamar — Adapty resuelve la solicitud según la audiencia que coincida con el estado actual del perfil, normalmente la audiencia por defecto.\n\n:::important\nLa espera solo aplica al **primer lanzamiento**. Una vez que la atribución de Apple Ads se ha registrado, queda almacenada en el perfil de forma permanente. En cada lanzamiento posterior, el perfil en caché ya lleva `.appleAds` en `appliedAttributionSources`, `didLoadLatestProfile` se dispara con ese valor de inmediato, y `getPaywall` devuelve el paywall segmentado por Apple Ads sin ningún retraso.\n:::"},"h2-implementation-p0489292f":{"contentHash":"sha256:0489292f1693789277f40f79d952b8e2e1ab4dbe3b9660b28c778ac27cfb505a","proseHash":"sha256:0489292f1693789277f40f79d952b8e2e1ab4dbe3b9660b28c778ac27cfb505a","translation":"## Implementación \\{#implementation\\}\n\nAl primer lanzamiento, comprueba si hay `.appleAds` en el perfil y aplica un tiempo de espera máximo: si la atribución de Apple Ads nunca llega, esos usuarios igualmente necesitan ver un paywall."},"h2-implementation-p270705c8":{"contentHash":"sha256:270705c8ed16258601468ece248d7d17b8175cd8ec2c96c56c7394f27d196a94","proseHash":"sha256:270705c8ed16258601468ece248d7d17b8175cd8ec2c96c56c7394f27d196a94","translation":"1. **Activa el SDK.** Consulta [Instalar y configurar el SDK de iOS](sdk-installation-ios).\n2. **Suscríbete a las actualizaciones del perfil** implementando `AdaptyDelegate` y el método `didLoadLatestProfile`. Si aún no has configurado el delegate, consulta [Escuchar actualizaciones de suscripción](ios-check-subscription-status#listen-to-subscription-updates).\n3. **Observa `.appleAds` en `appliedAttributionSources`.** Cuando aparezca, solicita el paywall — Adapty devolverá la variante segmentada por ASA:"},"h2-implementation-pe6c8a5aa":{"contentHash":"sha256:0b38615aa43b5a372ac18648b74c9e29f635e33dddbcfffb50c36eb27058255a","proseHash":"sha256:e6c8a5aac7419f62966c044836dd657783b3481714ed14d28b027821e9834d4d","translation":"```swift\nextension <YourAdaptyDelegateImpl>: AdaptyDelegate {\n nonisolated func didLoadLatestProfile(_ profile: AdaptyProfile) {\n if profile.appliedAttributionSources.contains(where: { $0 == .appleAds }) {\n // load paywall via Adapty.getPaywall(placementId:)\n }\n }\n}\n```\n\n4. **Inicia un temporizador de 3–5 segundos en paralelo con la suscripción.** Si el temporizador se activa antes de que aparezca `.appleAds`, solicita el paywall de todas formas:"},"h2-implementation-pa9f96281":{"contentHash":"sha256:a9f962813dd90a70bf7507a16487850a9aa126c8764767790ec2d85b00bd6a44","proseHash":"sha256:a9f962813dd90a70bf7507a16487850a9aa126c8764767790ec2d85b00bd6a44","translation":"Sea cual sea el camino que se active primero, debe cargar el paywall; el otro camino debe omitirse. Usa un único indicador de estado (por ejemplo, `hasLoadedPaywall`) para deduplicar y evitar que el paywall se obtenga dos veces. Configura un [paywall de respaldo](fallback-paywalls) para el placement para que el usuario nunca se quede bloqueado si falla la solicitud de red."},"h2-complete-example-p324dfea1":{"contentHash":"sha256:324dfea1ff7e4cf2d3e8925fcb6b9b43d87638526ab840e26cac37872e375bed","proseHash":"sha256:324dfea1ff7e4cf2d3e8925fcb6b9b43d87638526ab840e26cac37872e375bed","translation":"## Ejemplo completo \\{#complete-example\\}\n\nLa implementación que se muestra a continuación enfrenta la atribución contra un tiempo límite, precarga el paywall de la audiencia predeterminada en paralelo y devuelve el paywall que corresponda. Quien llame a la función solo tiene que esperar a una única función asíncrona — sin delegados ni indicadores de estado que gestionar en el punto de llamada.\n\n`ProfileObserver` es un singleton reutilizable que publica las actualizaciones del perfil desde `AdaptyDelegate`. `PaywallLoader.getPaywallOrDefault` ejecuta la carrera usando un `TaskGroup` de concurrencia estructurada:"},"h2-complete-example-p44980956":{"contentHash":"sha256:4498095610e1d50afbc06dbf646ce7244e19195faed2a2a9204101ed3d75a6b5","proseHash":"sha256:4498095610e1d50afbc06dbf646ce7244e19195faed2a2a9204101ed3d75a6b5","translation":"- Si la atribución llega dentro del `timeout`, devuelve el paywall segmentado mediante `getPaywall(placementId:)`.\n- Si el `timeout` expira primero, devuelve el paywall de audiencia predeterminada prefetcheado mediante `getPaywallForDefaultAudience(placementId:)`."},"h2-complete-example-pe3b0c442":{"contentHash":"sha256:5ddcbba5923d9fb34947835495a6becc3aba1b2cb4652cfdbb814644be28e4dc","proseHash":"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","translation":"```swift title=\"PaywallLoader.swift\"\nimport Adapty\nimport Combine\n\n/// Demuestra cómo obtener un paywall que depende de que se aplique la atribución,\n/// recurriendo al paywall de audiencia predeterminada si la atribución no llega a tiempo.\n///\n/// Sin estado y autocontenido: cada llamada inicia su propia precarga de audiencia\n/// predeterminada y la compite contra la obtención segmentada con atribución.\nenum PaywallLoader {\n static func getPaywallOrDefault(\n placementId: String,\n timeout: TimeInterval\n ) async throws -> AdaptyPaywall {\n struct TimedOut: Error {}\n\n // Iniciamos la solicitud de audiencia predeterminada de inmediato para que\n // tenga toda la ventana `timeout` para cargarse. La cancelaremos si tenemos\n // éxito, o esperaremos su resultado si hay timeout — nunca una llamada de red duplicada.\n let defaultPaywallTask = Task {\n try await Adapty.getPaywallForDefaultAudience(placementId: placementId)\n }\n\n do {\n // Competimos dos tareas hijas: la que termine primero gana.\n let result = try await withThrowingTaskGroup(of: AdaptyPaywall.self) { group in\n // 1. Esperamos la atribución y luego pedimos a Adapty el paywall segmentado.\n group.addTask {\n await waitForAttribution()\n return try await Adapty.getPaywall(placementId: placementId)\n }\n // 2. Bomba de tiempo: lanza `TimedOut` tras `timeout` segundos.\n group.addTask {\n try await Task.sleep(nanoseconds: UInt64(timeout * 1_000_000_000))\n throw TimedOut()\n }\n guard let value = try await group.next() else { throw CancellationError() }\n group.cancelAll() // detiene al perdedor (el temporizador o la espera de atribución).\n return value\n }\n // Ganó el paywall segmentado — ya no necesitamos la precarga de audiencia predeterminada.\n defaultPaywallTask.cancel()\n return result\n } catch is TimedOut {\n // La atribución no se aplicó a tiempo — devolvemos la precarga predeterminada\n // (instantánea si ya terminó, o esperamos la solicitud en vuelo).\n return try await defaultPaywallTask.value\n }\n }\n\n /// Suspende hasta que se observe un perfil con la fuente de atribución deseada.\n /// `@Published.values` emite el perfil actual de inmediato al suscribirse,\n /// por lo que devuelve en la primera iteración si la atribución ya está aplicada.\n @MainActor\n private static func waitForAttribution() async {\n for await profile in ProfileObserver.shared.$profile.values {\n if profile?.appliedAttributionSources.contains(.appleAds) == true { return }\n }\n }\n}\n\n@MainActor\nfinal class ProfileObserver: AdaptyDelegate {\n static let shared = ProfileObserver()\n\n @Published private(set) var profile: AdaptyProfile?\n\n nonisolated func didLoadLatestProfile(_ profile: AdaptyProfile) {\n Task { @MainActor [weak self] in\n self?.profile = profile\n }\n }\n}\n```"},"h2-complete-example-p9b7ca8a2":{"contentHash":"sha256:148095207b5e7962b3d71b490c40bef9df5d1f51c95b8feb47134aafa3cba379","proseHash":"sha256:9b7ca8a29ea92861292a5d48a5174d42c9a5d8b8bbb6592148a9a3c79e493fa9","translation":"Conecta `ProfileObserver` con `AdaptyDelegate` una vez, tras completar `Adapty.activate()`:\n\n```swift\nAdapty.delegate = ProfileObserver.shared\n```\n\nLlama desde la pantalla de carga:\n\n```swift\ndo {\n let paywall = try await PaywallLoader.getPaywallOrDefault(\n placementId: \"YOUR_PLACEMENT_ID\",\n timeout: 5\n )\n // present the paywall\n} catch {\n // handle the error or show a fallback paywall\n}\n```"},"h2-complete-example-p4fafe97d":{"contentHash":"sha256:4fafe97d71f26a6afd8f793627dcef7866103c25a744ffb13d4d81dee19e848c","proseHash":"sha256:4fafe97d71f26a6afd8f793627dcef7866103c25a744ffb13d4d81dee19e848c","translation":"Si tu app ya usa un `AdaptyDelegate` para otros fines (por ejemplo, [escuchar actualizaciones de suscripción](ios-check-subscription-status#listen-to-subscription-updates)), reenvía `didLoadLatestProfile` a `ProfileObserver.shared` desde tu delegado existente en lugar de establecer `Adapty.delegate = ProfileObserver.shared`."}}}

0 commit comments

Comments
 (0)