capgo/capacitor-widget-kit を使用すると、@
@capgo/capacitor-widget-kit Capacitor アプリは、WidgetKit と Live Activity の体験を 2 つの方法で実行できます:
- 解決された SVG テンプレート表面をフレーム切り替え、タップホットスポット、タイマー停止/再生でレンダリングします。
- アプリとウィジェットがJSONセッション状態と非同期メッセージを共有する場合、ウィジェットを完全にネイティブに保ちましょう。
インストール
bun add @capgo/capacitor-widget-kit
bunx cap sync
SVGテンプレートを使用するとき
ウィジェットの表面がSVGで表現できる場合、SVGテンプレートを使用します。アプリはテンプレート定義を保存し、ネイティブブリッジはプレースホルダを解決し、ウィジェットのタップは後で状態を変えることができます。
適切な例には、トレーニングタイマーや配達状況カード、スポーツスコア、または名前付きフレーム間で切り替えるだけで済むコンパクト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>`,
},
],
},
},
},
});
アプリ内でウィジェットアクションを処理する
ウィジェットアクションはイベントとして保存されます。アプリが再開したりバックグラウンドシンクステップ後にそれらを読み取り、承認する必要があります。
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 });
フルネイティブセッションを使用するとき
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 },
});
ウィジェットとアプリの間で非同期作業をキューイング
メッセージはアプリからウィジェットへまたはウィジェットからアプリへ流れます。メッセージは承認され、完了するまで待機します。
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',
});
セッションを適切に終了する
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 ファイルに設定します。 インタラクティブなボタンには、プラグインが提供するネイティブブリッジとアクションの意図を接続するウィジェット拡張機能が必要です。
フルリファレンス
- GitHub: https://github.com/Cap-go/capacitor-widget-kit/
- ドキュメント: /docs/plugins/widget-kit/
Capgoの@capgo/capacitor-widget-kitを使用している場合
Capgoの@__CAPGO_KEEP_0__/__CAPGO_KEEP_1__-widget-kitを使用している場合 Using @capgo/capacitor-widget-kit native プラグインの作業計画を立てるには、接続する @capgo/capacitor-widget-kit for the implementation detail in @capgo/capacitor-widget-kit, Getting Started Capacitor-Widget-Kitの実装詳細について Capgo プラグイン ディレクトリ for the product workflow in Capgo Plugin Directory, Capacitor Plugins by Capgo for the implementation detail in Capacitor Plugins by Capgo, and プラグインの追加または更新 プラグインの追加または更新の実装詳細について