Gestionar eventos de onboarding en el SDK de iOS

A partir del SDK v4 (beta), puedes crear flows como una alternativa más potente a los onboardings. A diferencia de los onboardings, que se ejecutan dentro de un WebView, los flows se renderizan de forma nativa en el dispositivo, lo que ofrece animaciones más fluidas, una apariencia coherente con iOS, tiempos de carga más rápidos y sin dependencia del runtime de WebView. Consulta Obtener flows y paywalls y Mostrar flows y paywalls para empezar.

Antes de comenzar, asegúrate de que:

  1. Has instalado el SDK de Adapty para iOS 3.8.0 o posterior.
  2. Has creado un onboarding.
  3. Has añadido el onboarding a un placement.

Los onboardings configurados con el builder generan eventos a los que tu app puede responder. A continuación se explica cómo hacerlo.

Para controlar o supervisar los procesos que ocurren en la pantalla del onboarding dentro de tu app, implementa los métodos de AdaptyOnboardingControllerDelegate.

Acciones personalizadas

En el builder, puedes añadir una acción personalizada a un botón y asignarle un ID.

ios-events-1.webp

Luego puedes usar este ID en tu código y gestionarlo como una acción personalizada. Por ejemplo, si el usuario pulsa un botón personalizado, como Login o Allow notifications, el método delegado onboardingController se activará con el caso .custom(id:) y el parámetro actionId será el Action ID definido en el builder. Puedes crear tus propios IDs, como “allowNotifications”.

func onboardingController(_ controller: AdaptyOnboardingController, onCustomAction action: AdaptyOnboardingsCustomAction) {
    if action.actionId == "allowNotifications" {
        // Request notification permissions
    }
}
    
func onboardingController(_ controller: AdaptyOnboardingController, didFailWithError error: AdaptyUIError) {
    // Handle errors
}
Ejemplo de evento (haz clic para expandir)
{
  "actionId": "allowNotifications",
  "meta": {
    "onboardingId": "onboarding_123",
    "screenClientId": "profile_screen",
    "screenIndex": 0,
    "screensTotal": 3
  }
}

Cierre del onboarding

El onboarding se considera cerrado cuando el usuario pulsa un botón con la acción Close asignada.

ios-events-2.webp

Ten en cuenta que debes gestionar qué ocurre cuando el usuario cierra el onboarding. Por ejemplo, necesitas dejar de mostrar el onboarding.

Por ejemplo:

func onboardingController(_ controller: AdaptyOnboardingController, onCloseAction action: AdaptyOnboardingsCloseAction) {
    controller.dismiss(animated: true)
}
Ejemplo de evento (haz clic para expandir)
{
  "action_id": "close_button",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "final_screen",
    "screen_index": 3,
    "total_screens": 4
  }
}

Abrir un paywall

Maneja este evento para abrir un paywall dentro del onboarding. Si quieres abrirlo después de que se cierre el onboarding, hay una forma más directa de hacerlo: maneja AdaptyOnboardingsCloseAction y abre el paywall sin depender de los datos del evento.

La forma más fluida de trabajar con paywalls en onboardings es que el ID de acción sea igual al ID de placement del paywall. Así, tras recibir AdaptyOnboardingsOpenPaywallAction, puedes usar el ID de placement para obtener y abrir el paywall directamente. Ten en cuenta que solo se puede mostrar una vista (paywall u onboarding) en pantalla a la vez. Si presentas un paywall encima de un onboarding, no podrás controlar el onboarding en segundo plano de forma programática. Si intentas cerrar el onboarding, se cerrará el paywall en su lugar, dejando el onboarding visible. Para evitar esto, cierra siempre la vista del onboarding antes de presentar el paywall.

func onboardingController(_ controller: AdaptyOnboardingController, onPaywallAction action: AdaptyOnboardingsOpenPaywallAction) {
    // Dismiss onboarding before presenting the flow
    controller.dismiss(animated: true) {
        Task {
            do {
                // Get the flow using the placement ID from the action
                let flow = try await Adapty.getFlow(placementId: action.actionId)

                // Get the flow configuration
                let flowConfiguration = try await AdaptyUI.getFlowConfiguration(
                    forFlow: flow
                )

                // Create and present the flow controller
                let flowController = try AdaptyUI.flowController(
                    with: flowConfiguration,
                    delegate: self
                )

                // Present the flow from the root view controller
                if let rootVC = UIApplication.shared.windows.first?.rootViewController {
                    rootVC.present(flowController, animated: true)
                }
            } catch {
                // Handle any errors that occur during flow loading
                print("Failed to present flow: \(error)")
            }
        }
    }
}
Ejemplo de evento (Haz clic para expandir)
{
    "action_id": "premium_offer_1",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "pricing_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}

Finalización de carga del onboarding

Cuando el onboarding termina de cargarse, se invocará este método:

func onboardingController(_ controller: AdaptyOnboardingController, didFinishLoading action: OnboardingsDidFinishLoadingAction) {
    // Handle loading completion
}
Ejemplo de evento (haz clic para expandir)
{
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "welcome_screen",
        "screen_index": 0,
        "total_screens": 4
    }
}

Seguimiento de navegación

El método onAnalyticsEvent se llama cuando ocurren distintos eventos de análisis durante el flow de onboarding. El objeto event puede ser de los siguientes tipos:

TipoDescripción
onboardingStartedCuando el onboarding se ha cargado
screenPresentedCuando se muestra cualquier pantalla
screenCompletedCuando se completa una pantalla. Incluye elementId opcional (identificador del elemento completado) y reply opcional (respuesta del usuario). Se activa cuando los usuarios realizan cualquier acción para salir de la pantalla.
secondScreenPresentedCuando se muestra la segunda pantalla
userEmailCollectedSe activa cuando se recoge el correo electrónico del usuario a través del campo de entrada
onboardingCompletedSe activa cuando un usuario llega a una pantalla con el ID final. Si necesitas este evento, asigna el ID final a la última pantalla.
unknownPara cualquier tipo de evento no reconocido. Incluye name (el nombre del evento desconocido) y meta (metadatos adicionales)
Cada evento incluye información meta con los siguientes campos:
CampoDescripción
-------------------------
onboardingIdIdentificador único del flow de onboarding
screenClientIdIdentificador de la pantalla actual
screenIndexPosición de la pantalla actual en el flow
screensTotalNúmero total de pantallas en el flow

A continuación se muestra un ejemplo de cómo puedes usar los eventos de análisis para el seguimiento:

func onboardingController(_ controller: AdaptyOnboardingController, onAnalyticsEvent event: AdaptyOnboardingsAnalyticsEvent) {
    switch event {
    case .onboardingStarted(let meta):
        // Track onboarding start
        trackEvent("onboarding_started", meta: meta)
    case .screenPresented(let meta):
        // Track screen presentation
        trackEvent("screen_presented", meta: meta)
    case .screenCompleted(let meta, let elementId, let reply):
        // Track screen completion with user response
        trackEvent("screen_completed", meta: meta, elementId: elementId, reply: reply)
    case .onboardingCompleted(let meta):
        // Track successful onboarding completion
        trackEvent("onboarding_completed", meta: meta)
    case .unknown(let meta, let name):
        // Handle unknown events
        trackEvent(name, meta: meta)
    // Handle other cases as needed
    }
}
Ejemplos de eventos (haz clic para ampliar)
// onboardingStarted
{
  "name": "onboarding_started",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "welcome_screen",
    "screen_index": 0,
    "total_screens": 4
  }
}

// screenPresented

{
    "name": "screen_presented",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "interests_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}

// screenCompleted

{
    "name": "screen_completed",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    },
    "params": {
        "element_id": "profile_form",
        "reply": "success"
    }
}

// secondScreenPresented

{
    "name": "second_screen_presented",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    }
}

// userEmailCollected

{
    "name": "user_email_collected",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "profile_screen",
        "screen_index": 1,
        "total_screens": 4
    }
}

// onboardingCompleted

{
    "name": "onboarding_completed",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "final_screen",
        "screen_index": 3,
        "total_screens": 4
    }
}