跳过主要内容
返回插件
@capgo/capacitor-widget-kit
教程
@capgo/capacitor-widget-kit

Widget Kit

从Capacitor中构建WidgetKit和Live Activity表面,使用SVG框架、计时器、动作热点或全本机控件状态同步

Demo

Animated WebP demos

WidgetKit 和 Live Activity 模板控件以动画 WebP 演示形式呈现。

源资产
使用 Capacitor 驱动的动画 WidgetKit 演示,显示模板小部件状态和控件
Widget 模板流程

指南

关于 Widget Kit 的教程

使用 @capgo/capacitor-widget-kit

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

  • 渲染解析的 SVG 模板表面,支持帧切换、触摸热点和暂停/播放计时器。
  • Keep the widget fully native while the app and widget share JSON session state and async messages.

Install

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

Install

Use SVG templates when the widget surface can be described as SVG. The app stores a template definition, the native bridge resolves placeholders, and widget taps can mutate state later.

Use SVG templates when the widget surface can be described as SVG. The app stores a template definition, the native bridge resolves placeholders, and widget taps can mutate state later.

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>`,
          },
        ],
      },
    },
  },
});

Good fits include workout timers, delivery status cards, sports scores, or any compact UI where switching between named frames is enough.

Handle Widget Actions In The App

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 });

Widget actions are persisted as events. Read and acknowledge them when the app resumes or after a background sync step.

Use full-native sessions when the widget UI is better built directly in Swift, Kotlin, or Java. Capacitor still starts and stops the session, keeps shared state current, and queues work between app and 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 },
});

Queue Async Work Between Widget And App

Messages can flow from app to widget or widget to app. They stay pending until acknowledged and completed.

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 },
});

If the job fails, complete the message with an error:

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

停止会话

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

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

原生设置说明

对于 iOS WidgetKit 和 Live Activities,配置应用组在应用和小部件扩展目标上,并设置 CapgoWidgetKitAppGroup 在两个 Info.plist 文件中。交互式按钮需要一个小部件扩展,连接了插件提供的原生桥接和动作意图。

完整参考

继续使用 @capgo/capacitor-widget-kit

如果您正在使用 使用 @capgo/capacitor-widget-kit 为了计划原生插件工作,连接它与 @capgo/capacitor-widget-kit 关于@capgo/capacitor-widget-kit的实现细节, 入门指南 关于入门指南的实现细节, Capgo 插件目录 关于Capgo 插件目录中的产品工作流程, Capacitor 由Capgo提供的插件 关于Capacitor 由Capgo提供的插件的实现细节, 添加或更新插件 关于添加或更新插件的实现细节。