Zum Inhalt springen

Einstieg

Terminalfenster
bun add @capgo/capacitor-widget-kit
bunx cap sync
import { CapgoWidgetKit } from '@capgo/capacitor-widget-kit';

Für Live-Aktivitäten und WidgetKit-Erweiterungen konfigurieren Sie die native App zuerst:

  • Verwenden Sie iOS 17+ für interaktive Live-Aktivitätsknöpfe, wenn möglich.
  • Hinzufügen NSSupportsLiveActivities zur App Info.plist wenn ActivityKit verwendet wird.
  • Fügen Sie dem gleichen App-Gruppen-Identifikator in beiden
  • in beiden Dateien CapgoWidgetKitAppGroup Dateien Info.plist zur geteilten App-Gruppen-Identifikator.
<key>CapgoWidgetKitAppGroup</key>
<string>group.app.capgo.widgetkit.exampleapp.widgetkit</string>
const { supported, reason } = await CapgoWidgetKit.areActivitiesSupported();
if (!supported) {
console.log('WidgetKit bridge unavailable:', reason);
}

Option 1: SVG-Vorlagenaktivität

Abschnitt: "Option 1: SVG-Vorlagenaktivität"

Verwenden Sie diesen Modus, wenn das Widget die gelösten SVGs rendern kann. Der Plugin speichert den Zustand, löst Platzhalter auf, legt Tastenaktionen fest, wechselt zwischen SVG-Frames und hält den Timerzustand konsistent.

const { activity } = await CapgoWidgetKit.startTemplateActivity({
activityId: 'workout-session-1',
openUrl: 'myapp://workout/session-1',
state: {
title: 'Chest Day',
frame: 'summary',
restDurationMs: 90000,
},
definition: {
id: 'workout-card',
timers: [
{
id: 'rest',
durationPath: 'state.restDurationMs',
},
],
actions: [
{
id: 'next-frame',
eventName: 'widget.frame.changed',
frameMutations: [
{
op: 'next',
path: 'frame',
surface: 'lockScreen',
},
],
},
{
id: 'toggle-rest',
eventName: 'widget.timer.toggled',
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>`,
},
],
},
},
},
});

Aktionen aus der App ausführen

Abschnitt: "Aktionen aus der App ausführen"

Nativ-Widgets können die gleichen Aktionen über ihre Hotspot/Aktion-Verkabelung auslösen. Die App kann sie auch direkt ausführen:

await CapgoWidgetKit.performTemplateAction({
activityId: activity.activityId,
actionId: 'toggle-rest',
sourceId: 'app-pause-play-button',
});

Widget Ereignisse verarbeiten

Abschnitt: Widget Ereignisse verarbeiten

Aktionen senden Ereignisse, damit die App nach dem Start oder Wiederaufnahme die Widget-Interaktionen verarbeiten kann:

const { events } = await CapgoWidgetKit.listTemplateEvents({
activityId: activity.activityId,
unacknowledgedOnly: true,
});
for (const event of events) {
console.log('Widget event:', event.eventName, event.state, event.timers);
}
await CapgoWidgetKit.acknowledgeTemplateEvents({
activityId: activity.activityId,
});

Aktivität aktualisieren oder beenden

Abschnitt: Aktivität aktualisieren oder beenden
await CapgoWidgetKit.updateTemplateActivity({
activityId: activity.activityId,
state: {
title: 'Back Day',
frame: 'summary',
restDurationMs: 120000,
},
});
await CapgoWidgetKit.endTemplateActivity({
activityId: activity.activityId,
state: { title: 'Workout complete', frame: 'summary' },
});

Frame-Mutationen schreiben den aktiven Frame-Id in den Zustand. Ein Layout kann ihn dann mit frameIdPath.

OperationVerhalten
setSetzen Sie eine bestimmte Frame-ID. Gleichlautende Zeichenketten werden als wörtliche Frame-IDs behandelt; Vorlagen werden zuerst aufgelöst. {{...}} Zum nächsten Frame wechseln von
nextoder den auf frameIds Zum vorherigen Frame wechseln. surface.
previousZwischen den ersten beiden verfügbaren Frames, oder zwischen dem aktuellen Frame und
toggleWird ignoriert, wenn die Mutation eine bekannte Auswahlmöglichkeit für Frame-IDs hat, sodass sich der Zustand mit der gerenderten Oberfläche synchronisiert. frameId.

Timer-Mutationen

Abschnitt mit dem Titel “Timer-Mutationen”

Timer-Mutationen richten sich an eine benannte Timer von

Operation definition.timers.

VerhaltenTimer Mutations
start / restartMit der aktuellen Dauer von vorne beginnen.
pauseGespeicherte Zeit und Zwischenzustand löschen startedAt.
resumeNur pausierte Timer werden fortgesetzt. Gesteuerte Timer bleiben bis zu einem expliziten Start oder Neustart gestoppt.
toggleEin laufenden Timer pausieren oder einen pausierte Timer fortsetzen.
resetGespeicherte Zeit und Zwischenzustand löschen und zurück in den Idle-Zustand gehen.
stopLaufzeitfortschritt löschen und den Timer als gestoppt markieren.
setDurationStatus nach einer Daueränderung neu berechnen.

Timer-Bindings sind für SVG als __CAPGO_KEEP_0__, und verwandte Felder verfügbar. {{timers.<id>.remainingText}}, {{timers.<id>.elapsedMs}}, {{timers.<id>.status}}Option 2: Vollständig-Nativer Widget-Sitzung

Use this mode when the widget UI is built in native code. The plugin gives the app and widget a shared session record and a message queue.

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 { sessions } = await CapgoWidgetKit.listWidgetSessions();
console.log('Known widget sessions:', sessions);

Die Nachrichten behandeln Arbeit, die eine späterige Antwort erfordert, wie ein Widget, das die App auffordert, Daten zu synchronisieren.

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

Um den Job zu scheitern, passen Sie error anstatt response:

await CapgoWidgetKit.completeWidgetMessage({
messageId: message.messageId,
error: 'Network unavailable',
});

completeWidgetMessage ist idempotent. Wenn die Nachricht bereits abgeschlossen oder gescheitert ist, wiederholte Aufrufe geben das bestehende Nachrichtensnapshot zurück.

await CapgoWidgetKit.stopWidgetSession({
widgetId: session.widgetId,
state: { isRunning: false },
});
GruppeAPIs
FähigkeitareActivitiesSupported, getPluginVersion
SVG-AktivitätslebenszyklusstartTemplateActivity, updateTemplateActivity, endTemplateActivity, getTemplateActivity, listTemplateActivities
SVG-Aktionen und EreignisseperformTemplateAction, listTemplateEvents, acknowledgeTemplateEvents
Native-Widget-SitzungenstartWidgetSession, updateWidgetSession, stopWidgetSession, getWidgetSession, listWidgetSessions
Native-Widget-NachrichtensendWidgetMessage, listWidgetMessages, acknowledgeWidgetMessages, completeWidgetMessage

Die vollständige Typenreferenz befindet sich im Plugin-Repository bei src/definitions.ts.