跳转至正文
@capgo/capacitor-widget-kit UI 与系统 开源

Widget Kit 入门指南 Capacitor 插件

通过 Capacitor 构建 WidgetKit 和 Live Activity 界面,支持 SVG 帧、计时器、操作热区,或完全原生的 Widget 状态同步

安装

bun add @capgo/capacitor-widget-kit bunx cap sync
npm、pnpm 或 yarn
  • npm install @capgo/capacitor-widget-kit
  • pnpm add @capgo/capacitor-widget-kit
  • yarn add @capgo/capacitor-widget-kit

演示

Widget Kit 演示

以 WebP 动画演示 WidgetKit 和 Live Activity 模板控件。

源文件
WidgetKit 动画演示,展示由 Capacitor 驱动的模板小组件状态和控件
Widget 模板流程

指南

如何在 Capacitor 中使用 Widget Kit

使用 @capgo/capacitor-widget-kit

@capgo/capacitor-widget-kit 让 Capacitor 应用通过以下两种方式驱动 WidgetKit 和 Live Activity 体验:

  • 通过帧切换、点击热点以及暂停/播放定时器,渲染解析后的 SVG 模板界面。
  • 保持 Widget 完全原生,同时让应用与 Widget 共享 JSON 会话状态和异步消息。

安装

bun add @capgo/capacitor-widget-kit
bunx cap sync

何时使用 SVG 模板

当 Widget 界面可以用 SVG 描述时,就用 SVG 模板。应用保存模板定义,原生桥接解析占位符,之后点击 Widget 即可改变状态。

适用场景包括健身计时器、配送状态卡片、体育比分,或任何只需在命名帧之间切换的紧凑 UI。

import { CapgoWidgetKit } from '@capgo/capacitor-widget-kit';

const { activity } = await CapgoWidgetKit.startTemplateActivity({
  activityId: 'session-1',
  state: {
    title: 'Chest Day',
    frame: 'summary',
    restDurationMs: 90000,
  },
  definition: {
    id: 'workout-card',
    timers: [{ id: 'rest', durationPath: 'state.restDurationMs' }],
    actions: [
      {
        id: 'next-frame',
        frameMutations: [{ op: 'next', path: 'frame', surface: 'lockScreen' }],
      },
      {
        id: 'toggle-rest',
        timerMutations: [{ op: 'toggle', timerId: 'rest' }],
      },
    ],
    layouts: {
      lockScreen: {
        width: 100,
        height: 40,
        frameIdPath: 'state.frame',
        frames: [
          {
            id: 'summary',
            hotspots: [{ id: 'switch', actionId: 'next-frame', x: 0, y: 0, width: 100, height: 40 }],
            svg: `<svg viewBox="0 0 100 40"><text x="6" y="22">{{state.title}}</text></svg>`,
          },
          {
            id: 'timer',
            hotspots: [{ id: 'pause-play', actionId: 'toggle-rest', x: 0, y: 0, width: 100, height: 40 }],
            svg: `<svg viewBox="0 0 100 40"><text x="6" y="22">{{timers.rest.remainingText}}</text></svg>`,
          },
        ],
      },
    },
  },
});

在应用中处理 Widget 操作

Widget 操作会作为事件持久化。请在应用恢复或后台同步完成后读取并确认这些事件。

const { events } = await CapgoWidgetKit.listTemplateEvents({
  activityId: activity.activityId,
  unacknowledgedOnly: true,
});

for (const event of events) {
  console.log(event.actionId, event.state, event.timers);
}

await CapgoWidgetKit.acknowledgeTemplateEvents({ activityId: activity.activityId });

何时使用 Full-Native Sessions

如果使用 Swift、Kotlin 或 Java 直接构建 Widget UI 效果更好,请使用 full-native sessions。Capacitor 仍负责启动和停止 session,保持共享状态同步,并在应用与 widget 之间排队 code。

const { session } = await CapgoWidgetKit.startWidgetSession({
  widgetId: 'native-session-1',
  kind: 'workout-controls',
  state: { isRunning: true, selectedSetId: 'set-1' },
  metadata: { accent: '#00d69c' },
});

await CapgoWidgetKit.updateWidgetSession({
  widgetId: session.widgetId,
  merge: true,
  state: { isRunning: false },
});

在 Widget 与应用之间排队异步任务

消息可以在应用与 widget 之间双向传递。在被确认并完成之前,它们将保持待处理状态。

const { message } = await CapgoWidgetKit.sendWidgetMessage({
  widgetId: session.widgetId,
  direction: 'widgetToApp',
  name: 'syncWorkoutSet',
  payload: { setId: 'set-1' },
  expectsResponse: true,
});

await CapgoWidgetKit.acknowledgeWidgetMessages({ messageIds: [message.messageId] });

await CapgoWidgetKit.completeWidgetMessage({
  messageId: message.messageId,
  response: { synced: true },
});

如果任务失败,请带上错误信息完成消息:

await CapgoWidgetKit.completeWidgetMessage({
  messageId: message.messageId,
  error: 'Sync failed',
});

优雅地停止 Session

await CapgoWidgetKit.endTemplateActivity({
  activityId: activity.activityId,
  state: { title: 'Workout complete', frame: 'summary' },
});

await CapgoWidgetKit.stopWidgetSession({
  widgetId: session.widgetId,
  state: { isRunning: false },
});

Native 配置注意事项

对于 iOS WidgetKit 和 Live Activities,请在 App 和 widget extension target 上配置 App Group,并设置 CapgoWidgetKitAppGroup 在两者中均需设置 Info.plist 文件。交互式按钮需要一个 widget extension,用于连接插件提供的 native bridge 和 action intent。

完整参考

继续阅读“使用 @capgo/capacitor-widget-kit”

如果你正在使用 使用 @capgo/capacitor-widget-kit 要规划原生插件工作,请将其与 @capgo/capacitor-widget-kit 有关 @capgo/capacitor-widget-kit 中的实现细节, 快速入门 有关“入门指南”中的实现细节, Capgo 插件目录 查看 Capgo 插件目录中的产品工作流, Capgo 提供的 Capacitor 插件 有关 Capgo 开发的 Capacitor 插件的实现细节,以及 添加或更新插件 有关添加或更新插件的实现细节。

常见问题

Widget Kit 插件常见问题

如何在 Capacitor 应用中安装 Widget Kit 插件?

运行 "bun add @capgo/capacitor-widget-kit"(或 "npm install @capgo/capacitor-widget-kit"),然后运行 "bunx cap sync",使 iOS 和 Android 项目同步原生 code。最后在你的应用 code 中从 "@capgo/capacitor-widget-kit" 导入即可。

@capgo/capacitor-widget-kit 是否支持 React、Vue 和 Angular?

支持。Widget Kit 是一个 Capacitor 包,因此它支持任何在 Capacitor 中运行的 Web 框架,包括 Ionic、React、Vue、Angular、Svelte 以及原生 JavaScript。

@capgo/capacitor-widget-kit 支持哪个版本的 Capacitor?

Capgo 插件遵循 Capacitor 的主版本号:请使用与 Capacitor 主版本号一致的插件主版本(例如插件 v8 对应 Capacitor 8)。GitHub README 中的兼容性表列出了仍在维护的版本。

@capgo/capacitor-widget-kit 是免费开源的吗?

是的。code 的源码已在 GitHub 公开,地址为 https://github.com/Cap-go/capacitor-widget-kit/,并且可以从 npm 免费安装。欢迎提交 Bug 报告和 Pull Request。

使用 Widget Kit 的 code 可以在不经过 App Store 审核的情况下更新吗?

安装或升级插件会改动原生 code,因此需要重新做一次商店构建。之后,调用该插件的 JavaScript、HTML 和 CSS 改动就能通过 Capgo live updates 立即发布。

无需等待 App 审核,即可发布 Widget Kit 更改

只要插件已包含在你的商店版本中,Capgo live updates 就能在几分钟内把 JavaScript、HTML 和 CSS 的改动推送给用户。

开始使用 Capgo