指南
如何在 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。
完整参考
- GitHub: https://github.com/Cap-go/capacitor-widget-kit/
- 文档:/docs/plugins/widget-kit/
继续阅读“使用 @capgo/capacitor-widget-kit”
如果你正在使用 使用 @capgo/capacitor-widget-kit 要规划原生插件工作,请将其与 @capgo/capacitor-widget-kit 有关 @capgo/capacitor-widget-kit 中的实现细节, 快速入门 有关“入门指南”中的实现细节, Capgo 插件目录 查看 Capgo 插件目录中的产品工作流, Capgo 提供的 Capacitor 插件 有关 Capgo 开发的 Capacitor 插件的实现细节,以及 添加或更新插件 有关添加或更新插件的实现细节。