Xử lý sự kiện onboarding trong iOS SDK

Bắt đầu từ SDK v4, bạn có thể xây dựng flows như một lựa chọn mạnh mẽ hơn so với onboarding. Khác với onboarding chạy bên trong WebView, flows render trực tiếp trên thiết bị — mang lại hoạt ảnh mượt mà hơn, giao diện iOS nhất quán, thời gian tải nhanh hơn và không phụ thuộc vào WebView runtime. Xem Lấy flows & paywallsHiển thị flows & paywalls để bắt đầu.

Trước khi bắt đầu, hãy đảm bảo rằng:

  1. Bạn đã cài đặt Adapty iOS SDK phiên bản 3.8.0 trở lên.
  2. Bạn đã tạo một onboarding.
  3. Bạn đã thêm onboarding vào một placement.

Các onboarding được cấu hình bằng builder sẽ tạo ra các sự kiện mà ứng dụng của bạn có thể phản hồi. Hãy tìm hiểu cách xử lý các sự kiện đó bên dưới.

Để kiểm soát hoặc theo dõi các tiến trình xảy ra trên màn hình onboarding trong ứng dụng của bạn, hãy triển khai các phương thức AdaptyOnboardingControllerDelegate.

Hành động tùy chỉnh

Trong builder, bạn có thể thêm hành động custom vào một nút và gán cho nó một ID.

ios-events-1.webp

Sau đó, bạn có thể sử dụng ID này trong code và xử lý nó như một hành động tùy chỉnh. Ví dụ: nếu người dùng nhấn vào một nút tùy chỉnh như Login hoặc Allow notifications, phương thức delegate onboardingController sẽ được kích hoạt với trường hợp .custom(id:) và tham số actionId chính là Action ID từ builder. Bạn có thể tự tạo các ID theo ý muốn, chẳng hạn như “allowNotifications”.

func onboardingController(_ controller: AdaptyOnboardingController, onCustomAction action: AdaptyOnboardingsCustomAction) {
    if action.actionId == "allowNotifications" {
        // Request notification permissions
    }
}
    
func onboardingController(_ controller: AdaptyOnboardingController, didFailWithError error: AdaptyUIError) {
    // Handle errors
}
Ví dụ sự kiện (Nhấp để mở rộng)
{
  "actionId": "allowNotifications",
  "meta": {
    "onboardingId": "onboarding_123",
    "screenClientId": "profile_screen",
    "screenIndex": 0,
    "screensTotal": 3
  }
}

Đóng onboarding

Onboarding được coi là đã đóng khi người dùng nhấn vào một nút có hành động Close được gán.

ios-events-2.webp

Lưu ý rằng bạn cần xử lý những gì xảy ra khi người dùng đóng onboarding. Ví dụ, bạn cần dừng việc hiển thị chính onboarding đó.

Ví dụ:

func onboardingController(_ controller: AdaptyOnboardingController, onCloseAction action: AdaptyOnboardingsCloseAction) {
    controller.dismiss(animated: true)
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "action_id": "close_button",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "final_screen",
    "screen_index": 3,
    "total_screens": 4
  }
}

Mở một paywall

Xử lý sự kiện này để mở paywall nếu bạn muốn mở nó bên trong onboarding. Nếu bạn muốn mở paywall sau khi nó được đóng lại, có một cách đơn giản hơn – xử lý AdaptyOnboardingsCloseAction và mở paywall mà không cần dựa vào dữ liệu sự kiện.

Cách liền mạch nhất để làm việc với paywall trong các onboarding là đặt action ID bằng với placement ID của paywall. Theo cách này, sau khi nhận được AdaptyOnboardingsOpenPaywallAction, bạn có thể dùng placement ID để lấy và mở paywall ngay lập tức.

Lưu ý rằng chỉ có thể hiển thị một màn hình (paywall hoặc onboarding) tại một thời điểm. Nếu bạn hiển thị một paywall chồng lên onboarding, bạn không thể lập trình để điều khiển onboarding ở phía sau. Việc cố gắng đóng onboarding sẽ đóng paywall thay vào đó, khiến onboarding vẫn hiển thị. Để tránh điều này, hãy luôn đóng màn hình onboarding trước khi hiển thị 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)")
            }
        }
    }
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
    "action_id": "premium_offer_1",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "pricing_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}

Hoàn thành tải onboarding

Khi một onboarding hoàn tất quá trình tải, phương thức này sẽ được gọi:

func onboardingController(_ controller: AdaptyOnboardingController, didFinishLoading action: OnboardingsDidFinishLoadingAction) {
    // Handle loading completion
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "welcome_screen",
        "screen_index": 0,
        "total_screens": 4
    }
}

Theo dõi điều hướng

Phương thức onAnalyticsEvent được gọi khi các sự kiện analytics khác nhau xảy ra trong quá trình onboarding.

Đối tượng event có thể thuộc một trong các kiểu sau:

KiểuMô tả
onboardingStartedKhi onboarding đã được tải
screenPresentedKhi bất kỳ màn hình nào được hiển thị
screenCompletedKhi một màn hình hoàn thành. Bao gồm elementId tùy chọn (định danh của phần tử đã hoàn thành) và reply tùy chọn (phản hồi từ người dùng). Được kích hoạt khi người dùng thực hiện bất kỳ hành động nào để thoát khỏi màn hình.
secondScreenPresentedKhi màn hình thứ hai được hiển thị
userEmailCollectedĐược kích hoạt khi email của người dùng được thu thập qua trường nhập liệu
onboardingCompletedĐược kích hoạt khi người dùng đến màn hình có ID final. Nếu bạn cần sự kiện này, hãy gán ID final cho màn hình cuối cùng.
unknownDành cho bất kỳ kiểu sự kiện không được nhận dạng nào. Bao gồm name (tên của sự kiện không xác định) và meta (siêu dữ liệu bổ sung)

Mỗi sự kiện bao gồm thông tin meta chứa:

TrườngMô tả
onboardingIdĐịnh danh duy nhất của flow onboarding
screenClientIdĐịnh danh của màn hình hiện tại
screenIndexVị trí của màn hình hiện tại trong flow
screensTotalTổng số màn hình trong flow

Dưới đây là ví dụ về cách bạn có thể sử dụng các sự kiện analytics để theo dõi:

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
    }
}
Ví dụ sự kiện (Nhấp để mở rộng)
// 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
    }
}