Migrar Adapty iOS SDK a la v. 4.0
Adapty iOS SDK 4.0 (beta) introduce los flows y renombra las APIs de paywall en consecuencia. Las nuevas APIs funcionan tanto con el nuevo Flow Builder como con el Paywall Builder existente — no se requieren cambios de configuración en el Adapty Dashboard.
Referencia rápida
| v3 | v4 |
|---|---|
Adapty.getPaywall(placementId:locale:) | Adapty.getFlow(placementId:) |
AdaptyUI.getPaywallConfiguration(forPaywall:) | AdaptyUI.getFlowConfiguration(forFlow:locale:) |
Adapty.getPaywallProducts(paywall:) | Adapty.getPaywallProducts(flow:) |
Adapty.logShowPaywall(_:) | Adapty.logShowFlow(_:) |
AdaptyPaywallController | AdaptyFlowController |
AdaptyPaywallControllerDelegate | AdaptyFlowControllerDelegate |
AdaptyUI.paywallController(with:delegate:) | AdaptyUI.flowController(with:delegate:) |
.paywall() (modificador SwiftUI) | .flow() |
AdaptyPaywallView | AdaptyFlowView |
didFailRenderingWith: / didFailRendering: | didReceiveError: |
Adapty.updateAttribution(_:source:) (source: String) | Adapty.updateAttribution(_:source:) (source: AdaptyAttributionSource) |
Adapty.setIntegrationIdentifier(key:value:) | Adapty.setIntegrationIdentifier(_:) (AdaptyIntegrationIdentifier) |
Instalación: CocoaPods ya no está soportado
El SDK de Adapty para iOS 4.0 elimina el soporte de CocoaPods. Instala el SDK con Swift Package Manager.
Si tu proyecto todavía usa CocoaPods, elimina los pods Adapty y AdaptyUI de tu Podfile, ejecuta pod install para limpiarlos y luego añade el paquete en Xcode desde File → Add Package Dependency usando https://github.com/adaptyteam/AdaptySDK-iOS.git.
APIs eliminadas
Adapty.getPaywallProductsWithoutDeterminingOffer(paywall:)— eliminada. Todos los productos incluyen ahora información sobre la oferta, por lo que el paso de elegibilidad separado ya no es necesario.AdaptyPaywallProductWithoutDeterminingOffer— eliminada. Los callbacks que antes pasaban este tipo (comodidSelectProduct) ahora pasanAdaptyPaywallProduct.
Obtener paywalls
getPaywall + getPaywallConfiguration → getFlow + getFlowConfiguration
Los tipos devueltos cambian de AdaptyPaywall / AdaptyUI.PaywallConfiguration a AdaptyFlow / AdaptyUI.FlowConfiguration. El parámetro locale deja de estar en la llamada de obtención y pasa a getFlowConfiguration:
- let paywall = try await Adapty.getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en")
- let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(forPaywall: paywall)
+ let flow = try await Adapty.getFlow(placementId: "YOUR_PLACEMENT_ID")
+ let flowConfiguration = try await AdaptyUI.getFlowConfiguration(forFlow: flow, locale: "en")
getPaywallProducts(paywall:) → getPaywallProducts(flow:)
getPaywallProducts ahora recibe un AdaptyFlow devuelto por Adapty.getFlow:
- let products = try await Adapty.getPaywallProducts(paywall: paywall)
+ let products = try await Adapty.getPaywallProducts(flow: flow)
Seguimiento de vistas de paywall
logShowPaywall(:) → logShowFlow(:)
logShowPaywall ha sido renombrado a logShowFlow y ahora recibe un AdaptyFlow en lugar de un AdaptyPaywall. El evento sigue registrándose contra la misma variación, por lo que las métricas de funnel y de prueba A/B existentes seguirán funcionando sin cambios en el dashboard.
- try await Adapty.logShowPaywall(paywall)
+ try await Adapty.logShowFlow(flow)
Al igual que en v3, no es necesario llamar a este método al mostrar flows o paywalls renderizados por el Flow Builder o el Paywall Builder — Adapty registra esas vistas automáticamente.
UIKit
AdaptyPaywallController → AdaptyFlowController
Renombra el tipo de controlador y el método factory:
- let controller = try AdaptyUI.paywallController(
- with: paywallConfiguration,
- delegate: self
- )
+ let controller = try AdaptyUI.flowController(
+ with: flowConfiguration,
+ delegate: self
+ )
AdaptyPaywallControllerDelegate → AdaptyFlowControllerDelegate
Renombra el protocolo y actualiza cada firma de método. Ten en cuenta que didSelectProduct ahora recibe AdaptyPaywallProduct en lugar del eliminado AdaptyPaywallProductWithoutDeterminingOffer.
- class YourClass: AdaptyPaywallControllerDelegate {
+ class YourClass: AdaptyFlowControllerDelegate {
- func paywallControllerDidAppear(_ controller: AdaptyPaywallController) { }
+ func flowControllerDidAppear(_ controller: AdaptyFlowController) { }
- func paywallControllerDidDisappear(_ controller: AdaptyPaywallController) { }
+ func flowControllerDidDisappear(_ controller: AdaptyFlowController) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didPerform action: AdaptyUI.Action) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didPerform action: AdaptyUI.Action) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didSelectProduct product: AdaptyPaywallProductWithoutDeterminingOffer) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didSelectProduct product: AdaptyPaywallProduct) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didStartPurchase product: AdaptyPaywallProduct) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didStartPurchase product: AdaptyPaywallProduct) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFinishPurchase product: AdaptyPaywallProduct,
- purchaseResult: AdaptyPurchaseResult) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFinishPurchase product: AdaptyPaywallProduct,
+ purchaseResult: AdaptyPurchaseResult) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFailPurchase product: AdaptyPaywallProduct,
- error: AdaptyError) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFailPurchase product: AdaptyPaywallProduct,
+ error: AdaptyError) { }
- func paywallControllerDidStartRestore(_ controller: AdaptyPaywallController) { }
+ func flowControllerDidStartRestore(_ controller: AdaptyFlowController) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFinishRestoreWith profile: AdaptyProfile) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFinishRestoreWith profile: AdaptyProfile) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFailRestoreWith error: AdaptyError) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFailRestoreWith error: AdaptyError) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFailRenderingWith error: AdaptyUIError) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didReceiveError error: AdaptyUIError) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFailLoadingProductsWith error: AdaptyError) -> Bool { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFailLoadingProductsWith error: AdaptyError) -> Bool { }
- func paywallController(_ controller: AdaptyPaywallController,
- didPartiallyLoadProducts failedIds: [String]) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didPartiallyLoadProducts failedIds: [String]) { }
- func paywallController(_ controller: AdaptyPaywallController,
- didFinishWebPaymentNavigation product: AdaptyPaywallProduct?,
- error: AdaptyError?) { }
+ func flowController(_ controller: AdaptyFlowController,
+ didFinishWebPaymentNavigation product: AdaptyPaywallProduct?,
+ error: AdaptyError?) { }
}
SwiftUI
Modificador .paywall() → .flow()
Renombra el modificador y actualiza el nombre del parámetro de configuración:
@State var flowPresented = false // rename freely — the variable name is your choice
var body: some View {
Text("Hello, AdaptyUI!")
- .paywall(
+ .flow(
isPresented: $flowPresented,
- paywallConfiguration: paywallConfiguration,
+ flowConfiguration: flowConfiguration,
didFailPurchase: { product, error in /* handle the error */ },
didFinishRestore: { profile in /* check access level and dismiss */ },
didFailRestore: { error in /* handle the error */ },
- didFailRendering: { error in flowPresented = false }
+ didReceiveError: { error in flowPresented = false }
)
}
El callback renombrado se activa para los mismos errores de renderizado que didFailRendering, más los nuevos errores en tiempo de ejecución del script del flow (excepciones de JavaScript con código AdaptyUIError 4105 — .jsException). Los cuerpos de los handlers existentes no necesitan cambios en el código: solo hay que renombrar el parámetro.
AdaptyPaywallView → AdaptyFlowView
Cambia el nombre de la vista, actualiza el parámetro de configuración y actualiza cualquier closure didSelectProduct — ahora recibe AdaptyPaywallProduct en lugar del eliminado AdaptyPaywallProductWithoutDeterminingOffer:
- AdaptyPaywallView(
- paywallConfiguration: paywallConfiguration,
- didSelectProduct: { product: AdaptyPaywallProductWithoutDeterminingOffer in /* handle */ },
+ AdaptyFlowView(
+ flowConfiguration: flowConfiguration,
+ didSelectProduct: { product: AdaptyPaywallProduct in /* handle */ },
didFailPurchase: { product, error in /* handle the error */ },
didFinishRestore: { profile in /* check access level and dismiss */ },
didFailRestore: { error in /* handle the error */ },
- didFailRendering: { error in /* handle the error */ }
+ didReceiveError: { error in /* handle the error */ }
)
Recursos personalizados de AdaptyUI
AdaptyUICustomVideoAsset
Hay dos cambios que afectan a todos los puntos de llamada existentes:
.playerahora aceptaAVPlayeren lugar deAVQueuePlayer.- Todos los casos han ganado un parámetro adicional al final:
resolution: CGSize?. Pasanilpara mantener el comportamiento actual, o pasa el tamaño en píxeles real para que el reproductor pueda reservar espacio de layout (relación de aspecto =width / height) antes de que cargue el vídeo.
- case file(url: URL, preview: AdaptyUICustomImageAsset?)
- case remote(url: URL, preview: AdaptyUICustomImageAsset?)
- case player(item: AVPlayerItem, player: AVQueuePlayer, preview: AdaptyUICustomImageAsset?)
+ case file(url: URL, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
+ case remote(url: URL, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
+ case player(item: AVPlayerItem, player: AVPlayer, preview: AdaptyUICustomImageAsset?, resolution: CGSize?)
Identificadores de atribución e integración
updateAttribution(_:source:)
El parámetro source cambia de String al nuevo tipo AdaptyAttributionSource, y el anteriormente anidado AdaptyProfile.AttributionSource se renombra al nivel superior AdaptyAttributionSource. Usa una de las fuentes predefinidas, o pasa un literal de cadena para cualquier otra fuente: AdaptyAttributionSource conforma con ExpressibleByStringLiteral, por lo que las llamadas con literales de cadena existentes siguen compilando.
- try await Adapty.updateAttribution(attribution, source: "adjust")
+ try await Adapty.updateAttribution(attribution, source: .adjust)
Fuentes predefinidas: .appleAds, .adjust, .appsflyer, .branch, .tenjin. Si guardas la fuente en una variable String, envuélvela así: AdaptyAttributionSource(rawValue: yourSource).
setIntegrationIdentifier(_:)
setIntegrationIdentifier(key:value:) es reemplazado por un método variádico que acepta uno o más valores de tipo AdaptyIntegrationIdentifier. Usa los métodos de fábrica predefinidos en lugar de claves de cadena sin formato:
- try await Adapty.setIntegrationIdentifier(key: "appsflyer_id", value: uid)
+ try await Adapty.setIntegrationIdentifier(.appsflyerId(uid))
Puedes establecer varios identificadores en una sola llamada:
try await Adapty.setIntegrationIdentifier(
.appsflyerId(uid),
.adjustDeviceId(adid)
)
Reemplaza cada cadena de clave antigua por su método de fábrica:
| clave v3 | factory v4 |
|---|---|
"adjust_device_id" | .adjustDeviceId(_:) |
"airbridge_device_id" | .airbridgeDeviceId(_:) |
"amplitude_user_id" | .amplitudeUserId(_:) |
"amplitude_device_id" | .amplitudeDeviceId(_:) |
"appmetrica_device_id" | .appmetricaDeviceId(_:) |
"appmetrica_profile_id" | .appmetricaProfileId(_:) |
"appsflyer_id" | .appsflyerId(_:) |
"branch_id" | .branchId(_:) |
"facebook_anonymous_id" | .facebookAnonymousId(_:) |
"firebase_app_instance_id" | .firebaseAppInstanceId(_:) |
"mixpanel_user_id" | .mixpanelUserId(_:) |
"one_signal_subscription_id" | .oneSignalSubscriptionId(_:) |
"one_signal_player_id" | .oneSignalPlayerId(_:) |
"posthog_distinct_user_id" | .posthogDistinctUserId(_:) |
"pushwoosh_hwid" | .pushwooshHWID(_:) |
"tenjin_analytics_installation_id" | .tenjinAnalyticsInstallationId(_:) |