在 Capacitor SDK 中处理用户引导事件

通过编辑工具配置的用户引导会生成相应事件,你的应用可以对这些事件作出响应。使用 setEventHandlers 方法来处理独立屏幕展示中的这些事件。

开始之前,请确保:

  1. 您已创建了用户引导
  2. 您已将用户引导添加到版位

设置事件处理器

要处理用户引导的事件,请使用 view.setEventHandlers 方法:


try {
  const view = await createOnboardingView(onboarding);
  
  view.setEventHandlers({
    onAnalytics(event, meta) {
      console.log('Analytics event:', event);
    },
    onClose(actionId, meta) {
      console.log('Onboarding closed:', actionId);
      return true; // Allow the onboarding to close
    },
    onCustom(actionId, meta) {
      console.log('Custom action:', actionId);
      return false; // Don't close the onboarding
    },
    onPaywall(actionId, meta) {
      console.log('Paywall action:', actionId);
      view.dismiss().then(() => {
        openPaywall(actionId);
      });
    },
    onStateUpdated(action, meta) {
      console.log('State updated:', action);
    },
    onFinishedLoading(meta) {
      console.log('Onboarding finished loading');
    },
    onError(error) {
      console.error('Onboarding error:', error);
    },
  });
  
  await view.present();
} catch (error) {
  console.error('Failed to present onboarding:', error);
}

事件类型

以下部分描述了您可以处理的不同类型的事件。

处理自定义操作

在付费墙编辑工具中,你可以为按钮添加 custom 操作,并为其指定一个 ID。

ios-events-1.webp

之后,你可以在代码中使用这个 ID,并将其作为自定义动作来处理。例如,当用户点击自定义按钮(如 LoginAllow notifications)时,事件处理器会以 actionId 参数触发,该参数与编辑工具中的 Action ID 相对应。你可以自定义 ID,例如 “allowNotifications”。

view.setEventHandlers({
  onCustom(actionId, meta) {
    switch (actionId) {
      case 'login':
        console.log('Login action triggered');
        break;
      case 'allow_notifications':
        console.log('Allow notifications action triggered');
        break;
    }
    return false; // Don't close the onboarding
  },
});
事件示例(点击展开)
{
  "actionId": "allow_notifications",
  "meta": {
    "onboardingId": "onboarding_123",
    "screenClientId": "profile_screen",
    "screenIndex": 0,
    "screensTotal": 3
  }
}

完成用户引导加载

当用户引导完成加载时,将触发以下事件:

view.setEventHandlers({
  onFinishedLoading(meta) {
    console.log('Onboarding loaded:', meta.onboardingId);
  },
});
事件示例(点击展开)
{
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "welcome_screen",
        "screen_index": 0,
        "total_screens": 4
    }
}

关闭用户引导

当用户点击分配了 Close 动作的按钮时,用户引导即视为已关闭。

ios-events-2.webp

请注意,你需要自行处理用户关闭用户引导后的逻辑。例如,需要停止显示用户引导界面本身。

view.setEventHandlers({
  onClose(actionId, meta) {
    console.log('Onboarding closed:', actionId);
    return true; // 允许关闭用户引导
  },
});
事件示例(点击展开)
{
  "action_id": "close_button",
  "meta": {
    "onboarding_id": "onboarding_123",
    "screen_cid": "final_screen",
    "screen_index": 3,
    "total_screens": 4
  }
}

打开付费墙

如果你想在用户引导内部打开付费墙,请处理此事件。如果你想在付费墙关闭后再打开一个付费墙,有一种更简便的方式——处理关闭操作并直接打开付费墙,无需依赖事件数据。

在用户引导中使用付费墙最顺畅的方式,是将操作 ID 设置为与付费墙版位 ID 相同。

请注意,在 iOS 上,屏幕上每次只能显示一个视图(付费墙或用户引导)。如果你在用户引导上方展示付费墙,则无法以编程方式控制后台的用户引导。尝试关闭用户引导时,实际上会关闭付费墙,导致用户引导仍然可见。为避免此问题,请始终在展示付费墙之前先关闭用户引导视图。

view.setEventHandlers({
  onPaywall(actionId, meta) {
    // 在展示付费墙之前关闭用户引导
    view.dismiss().then(() => {
      openPaywall(actionId);
    });
  },
});

async function openPaywall(placementId: string) {
  // 在此实现您的付费墙打开逻辑
}
事件示例(点击展开)
{
    "action_id": "premium_offer_1",
    "meta": {
        "onboarding_id": "onboarding_123",
        "screen_cid": "pricing_screen",
        "screen_index": 2,
        "total_screens": 4
    }
}

追踪导航

在用户引导流程中,每当发生与导航相关的事件时,你都会收到一个分析事件:

view.setEventHandlers({
  onAnalytics(event, meta) {
    console.log('Analytics event:', event.type, meta.onboardingId);
  },
});

event 对象可以是以下类型之一:

类型描述
onboardingStarted用户引导加载完成时触发
screenPresented任意页面显示时触发
screenCompleted页面完成时触发。包含可选的 elementId(已完成元素的标识符)和可选的 reply(用户的响应)。当用户执行任意操作退出页面时触发。
secondScreenPresented第二个页面显示时触发
userEmailCollected通过输入框收集到用户邮箱时触发
onboardingCompleted用户到达 ID 为 final 的页面时触发。如需使用该事件,请final ID 分配给最后一个页面
unknown用于任何无法识别的事件类型。包含 name(未知事件的名称)和 meta(附加元数据)。
每个事件都包含 meta 信息,内容如下:
字段描述
onboardingId用户引导流程的唯一标识符
screenClientId当前屏幕的标识符
screenIndex当前屏幕在流程中的位置
screensTotal流程中的屏幕总数
事件示例(点击展开)
// 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
    }
}