Skip to content

Commit 0844aba

Browse files
chore: update translations
1 parent 4993713 commit 0844aba

16 files changed

Lines changed: 681 additions & 4 deletions
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"fileHash":"sha256:34cd525bd7b9335a0c8cd469cafd4de707196ef0bcbf374f2ab32f19472c45ef","sections":{"preamble-p0a8dc688":{"contentHash":"sha256:0a8dc688f915d9a06090754a8b274772802f3f1e9450475f7c3ee46255e7369a","proseHash":"sha256:0a8dc688f915d9a06090754a8b274772802f3f1e9450475f7c3ee46255e7369a","translation":"---\ntitle: \"Mostrar un paywall segmentado por 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 segmentado por Apple Ads en el primer lanzamiento | iOS SDK | Documentación de Adapty\"\n---"},"preamble-p25b2ecbb":{"contentHash":"sha256:25b2ecbb8c68476f9f11baae47663764494d72c027e1a52760f3a19f20a72299","proseHash":"sha256:25b2ecbb8c68476f9f11baae47663764494d72c027e1a52760f3a19f20a72299","translation":"Apple Ads (AA) la atribución llega de forma asíncrona después de `Adapty.activate()`. Si llamas a `getPaywall` demasiado pronto, la atribución aún no ha llegado y Adapty resuelve el placement contra la audiencia predeterminada, saltándose tus paywalls segmentados por AA. `AdaptyProfile.appliedAttributionSources` permite a la app detectar cuándo se ha aplicado la atribución de AA al perfil, de modo que la solicitud del paywall pueda esperar hasta que la segmentación de AA 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-p8a87d84c":{"contentHash":"sha256:8a87d84cc1e1ab42f505693e6f0b1090a80e1abb3195989a3818225ea1c5adec","proseHash":"sha256:8a87d84cc1e1ab42f505693e6f0b1090a80e1abb3195989a3818225ea1c5adec","translation":"## Cómo funciona \\{#how-it-works\\}\n\nTras `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 AA 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 situaciones:\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 con la audiencia que coincida con el estado actual del perfil, normalmente la audiencia por defecto.\n\n:::important\nLa espera solo aplica en el **primer lanzamiento**. Una vez que la atribución de Apple Ads ha sido registrada, queda almacenada permanentemente en el perfil. En cada lanzamiento posterior, el perfil en caché ya incluye `.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\nEn el primer lanzamiento, controla la aparición de `.appleAds` en el perfil y aplica un timeout estricto: si la atribución de Apple Ads nunca llega, esos usuarios igualmente deben ver un paywall."},"h2-implementation-p6e331588":{"contentHash":"sha256:6e331588dcf2d0d71b4bac6cd6e6b5d1a42ebea1375873149f21055a86102708","proseHash":"sha256:6e331588dcf2d0d71b4bac6cd6e6b5d1a42ebea1375873149f21055a86102708","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 todavía 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 AA:"},"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 a 5 segundos en paralelo con la suscripción.** Si el temporizador se dispara antes de que aparezca `.appleAds`, solicita el paywall de todas formas:"},"h2-implementation-pa9f96281":{"contentHash":"sha256:a9f962813dd90a70bf7507a16487850a9aa126c8764767790ec2d85b00bd6a44","proseHash":"sha256:a9f962813dd90a70bf7507a16487850a9aa126c8764767790ec2d85b00bd6a44","translation":"Cualquiera de los dos caminos que se active primero debe cargar el paywall; el otro debe ignorarse. Usa un único indicador de estado (por ejemplo, `hasLoadedPaywall`) para deduplicar y evitar que el paywall se solicite dos veces. Configura un [paywall de respaldo](fallback-paywalls) para el placement para que el usuario nunca se quede bloqueado si la solicitud de red falla."},"h2-complete-example-p324dfea1":{"contentHash":"sha256:324dfea1ff7e4cf2d3e8925fcb6b9b43d87638526ab840e26cac37872e375bed","proseHash":"sha256:324dfea1ff7e4cf2d3e8925fcb6b9b43d87638526ab840e26cac37872e375bed","translation":"## Ejemplo completo \\{#complete-example\\}\n\nLa implementación que sigue ejecuta en paralelo la espera de la atribución con un timeout y la precarga del paywall de la audiencia por defecto, devolviendo el paywall apropiado según el resultado. El código que llama solo necesita hacer `await` a una única función asíncrona: sin delegados ni flags de estado en el punto de llamada.\n\n`ProfileObserver` es un singleton reutilizable que publica actualizaciones del perfil desde `AdaptyDelegate`. `PaywallLoader.getPaywallOrDefault` ejecuta la carrera mediante 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 la audiencia predeterminada prefetchado 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/// usando como respaldo el paywall de la audiencia predeterminada si la atribución\n/// no llega a tiempo.\n///\n/// Sin estado y autocontenido: cada llamada inicia su propia solicitud anticipada\n/// para la audiencia predeterminada y la compite contra la obtención segmentada\n/// 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 de `timeout` para cargarse. La cancelaremos si\n // hay éxito, o esperaremos su resultado si se agota el tiempo; nunca\n // habrá una llamada de red duplicada.\n let defaultPaywallTask = Task {\n try await Adapty.getPaywallForDefaultAudience(placementId: placementId)\n }\n\n do {\n // Competimos dos tareas secundarias: gana la que termine primero.\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. Temporizador: 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 la tarea perdedora (el temporizador o la espera de atribución).\n return value\n }\n // Ganó el paywall segmentado: ya no necesitamos la solicitud anticipada de la audiencia predeterminada.\n defaultPaywallTask.cancel()\n return result\n } catch is TimedOut {\n // La atribución no se aplicó a tiempo: devolvemos el resultado anticipado\n // de la audiencia predeterminada (instantáneo si ya terminó; si no,\n // esperamos la solicitud en curso).\n return try await defaultPaywallTask.value\n }\n }\n\n /// Suspende hasta que se observa un perfil con la fuente de atribución deseada.\n /// `@Published.values` emite el perfil actual de inmediato al suscribirse,\n /// por lo que retorna 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` a `AdaptyDelegate` una vez, después de que `Adapty.activate()` termine:\n\n```swift\nAdapty.delegate = ProfileObserver.shared\n```\n\nLlámalo desde la pantalla de inicio:\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)