Zum Inhalt springen

Erste Schritte

GitHub

Du kannst unser KI-gestütztes Setup nutzen, um das Plugin zu installieren. Füge die Capgo Skills mit dem folgenden Befehl deinem KI-Tool hinzu:

Terminalfenster
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins

Nutze dann diesen Prompt:

Use the `capacitor-plugins` skill from `Cap-go/capgo-skills` to install the `@capgo/capacitor-live-activities` plugin in my project.

Wenn du ein manuelles Setup bevorzugst, installiere das Plugin mit den folgenden Befehlen und befolge die plattformspezifischen Anweisungen unten:

Terminalfenster
bun add @capgo/capacitor-live-activities
bunx cap sync

Installation und Synchronisierung des Plugins erzeugen nicht die native Live Activity UI. ActivityKit benötigt eine Widget Extension, die eine Live-Activity-Konfiguration registriert, bevor startActivity etwas anzeigen kann.

  • Verwende iOS 16.1 oder neuer für das App-Target und das Widget-Extension-Target.
  • Teste auf einem iOS-Gerät oder einem kompatiblen Simulator. Die Dynamic Island erscheint nur auf unterstützten Gerätemodellen; andere Geräte nutzen die Darstellung auf dem Lock Screen.
  • Halte die kombinierten statischen und dynamischen ActivityKit-Daten unter dem 4-KB-Limit von Apple.

1. Erstelle eine Widget Extension

Abschnitt: „1. Widget Extension erstellen“

Öffne das native iOS-Projekt:

Terminalfenster
bunx cap open ios

Danach:

  1. Wähle Datei > Neu > Target.
  2. Füge einen Widget-Extension.
  3. Aktivieren Live Activity einschließen.
  4. Deaktivieren Configuration Intent hinzufügen es sei denn, die App benötigt auch ein konfigurierbares Widget.
  5. Stelle sicher, dass die generierte Extension in das Haupt-App-Target eingebettet ist.

Die Widget Extension muss einen ActivityConfiguration und ihn in seinem WidgetBundleregistrieren. Sie muss jede erforderliche Live Activity Präsentation bereitstellen:

  • Sperrbildschirm
  • Dynamic Island (expanded)
  • Dynamic Island (compact leading/trailing)
  • Dynamic Island (minimal)

Das bloße Hinzufügen des Targets reicht nicht aus. Die native App oder das Plugin muss die request-, update- und end-APIs von ActivityKit aufrufen. Die Extension muss SwiftUI code enthalten, die denselben ActivityAttributes und Content State dekodieren und rendern können, der in diesen Aufrufen verwendet wird. Binde gemeinsame ActivityKit-Modelle sowohl in das Haupt-App- als auch in das Widget Extension Target ein. Das von Xcode generierte Live Activity Template rendert die an dieses Plugin übergebenen JSON-Layouts nicht automatisch; die Extension benötigt ebenfalls einen kompatiblen nativen Layout-Renderer.

Füge den folgenden Key zum Haupt-App-Target hinzu: Info.plist:

<key>NSSupportsLiveActivities</key>
<true/>

Falls das Projekt seine Info.plist, füge Unterstützt Live Activities mit einem Boolean-Wert von YES stattdessen unter den Custom iOS Target Properties des Haupt-App-Targets.

Eine App Group wird nur benötigt, wenn Sie saveImage, removeImage, listImages, oder cleanupImages. Das Plugin leitet den App Group Identifier aus dem Bundle Identifier der Haupt-App in genau diesem Format ab:

group.<MAIN_APP_BUNDLE_ID>.liveactivities

Zum Beispiel eine App mit Bundle Identifier com.example.delivery muss verwenden:

group.com.example.delivery.liveactivities

Füge in Xcode die App-Gruppen füge die Capability sowohl dem Haupt-App-Target als auch dem Widget Extension Target hinzu und aktiviere anschließend denselben Identifier für beide Targets.

Live Activity Extensions haben keinen Netzwerkzugriff. Lade Remote-Bilder in der Haupt-App herunter und speichere sie im gemeinsamen App-Group-Speicher, bevor du sie in einer Live Activity referenzierst. Bei gebündelten Bildern aktiviere außerdem die Widget Extension in der Target Membership des Assets.

Bei Verwendung von behavior.widgetUrl oder eine Timer-Sequenz tapUrl, registriere das passende URL-Scheme oder den Universal Link in der Haupt-App. Für ein benutzerdefiniertes Scheme wie myapp://order/12345, füge das Scheme unter dem Haupt-App-Target hinzu Info > URL-Typen .

Push-Benachrichtigungen sind für lokale Updates, die von der App initiiert werden, nicht erforderlich. Um Live Activities von einem Server aus zu starten, zu aktualisieren oder zu beenden:

  • Füge den Push-Benachrichtigungen Capability zum Haupt-App-Target hinzu.
  • ActivityKit-Push-Tokens abrufen und an den Server senden.
  • ActivityKit-Benachrichtigungen über APNs mit dem liveactivity Push-Typ.
  • Füge NSSupportsLiveActivitiesFrequentUpdates an die Haupt-App Info.plist nur wenn der Anwendungsfall häufige Push-Updates erfordert.

ActivityKit-Push-Tokens sind getrennt von den Standard-Device-Tokens für Benutzerbenachrichtigungen. Das Aktivieren der Push Notifications Capability allein reicht nicht aus; servergesteuerte Updates erfordern natives Token-Handling und ein APNs-Backend.

Bevor Sie aufrufen startActivity, vergewissern Sie sich, dass:

  • NSSupportsLiveActivities im Haupt-App-Target aktiviert ist.
  • Die Widget Extension ist eingebettet und registriert einen ActivityConfiguration.
  • Die native ActivityKit-Implementierung und die Widget Extension nutzen denselben ActivityAttributes Typ.
  • Die Deployment-Targets für die App und die Widget Extension sind iOS 16.1 oder neuer.
  • Live Activities müssen in den iOS-Einstellungen für die App aktiviert sein.
  • Bei der Verwendung gemeinsamer Bilder muss die entsprechende App Group für beide Targets aktiviert sein.
  • Alle benutzerdefinierten URL-Schemes, die von widgetUrl oder tapUrl verwendet werden, sind registriert.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { supported, reason } = await CapgoLiveActivities.areActivitiesSupported();
if (supported) {
console.log('Live Activities are supported!');
} else {
console.log('Not supported:', reason);
}
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activityId } = await CapgoLiveActivities.startActivity({
layout: {
type: 'container',
direction: 'horizontal',
children: [
{ type: 'text', content: 'Order #{{orderNumber}}', fontSize: 16, fontWeight: 'bold' },
{ type: 'text', content: '{{status}}', fontSize: 14, color: '#666666' }
]
},
dynamicIslandLayout: {
expanded: {
leading: { type: 'image', source: 'sfSymbol', value: 'box.truck' },
trailing: { type: 'text', content: '{{eta}}' },
center: { type: 'text', content: '{{status}}' },
bottom: { type: 'progress', value: 'progress' }
},
compactLeading: { type: 'image', source: 'sfSymbol', value: 'box.truck' },
compactTrailing: { type: 'text', content: '{{eta}}' },
minimal: { type: 'image', source: 'sfSymbol', value: 'box.truck' }
},
data: {
orderNumber: '12345',
status: 'On the way',
eta: '10 min',
progress: 0.6
}
});
console.log('Started activity:', activityId);
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.updateActivity({
activityId: 'abc123',
data: {
status: 'Arrived!',
eta: 'Now',
progress: 1.0
},
alertConfiguration: {
title: 'Delivery Update',
body: 'Your order has arrived!'
}
});
  • Listener: Handles beim Unmounten von Screens entfernen.
  • Nativer Sync: ausführen bunx cap sync nach Plugin-Upgrades.
  • Single Source of Truth: Vertrauen src/definitions.ts im GitHub Repo.

Prüft, ob Live Activities auf diesem Gerät unterstützt werden. Erfordert iOS 16.1+ und entsprechende Geräteunterstützung.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { supported, reason } = await CapgoLiveActivities.areActivitiesSupported();
if (supported) {
console.log('Live Activities are supported!');
} else {
console.log('Not supported:', reason);
}

Eine neue Live Activity mit dem angegebenen Layout und den angegebenen Daten starten.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activityId } = await CapgoLiveActivities.startActivity({
layout: {
type: 'container',
direction: 'horizontal',
children: [
{ type: 'text', content: 'Order #{{orderNumber}}', fontSize: 16, fontWeight: 'bold' },
{ type: 'text', content: '{{status}}', fontSize: 14, color: '#666666' }
]
},
dynamicIslandLayout: {
expanded: {
leading: { type: 'image', source: 'sfSymbol', value: 'box.truck' },
trailing: { type: 'text', content: '{{eta}}' },
center: { type: 'text', content: '{{status}}' },
bottom: { type: 'progress', value: 'progress' }
},
compactLeading: { type: 'image', source: 'sfSymbol', value: 'box.truck' },
compactTrailing: { type: 'text', content: '{{eta}}' },
minimal: { type: 'image', source: 'sfSymbol', value: 'box.truck' }
},
data: {
orderNumber: '12345',
status: 'On the way',
eta: '10 min',
progress: 0.6
}
});
console.log('Started activity:', activityId);

Eine bestehende Live Activity mit neuen Daten aktualisieren.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.updateActivity({
activityId: 'abc123',
data: {
status: 'Arrived!',
eta: 'Now',
progress: 1.0
},
alertConfiguration: {
title: 'Delivery Update',
body: 'Your order has arrived!'
}
});

Eine Live Activity beenden.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.endActivity({
activityId: 'abc123',
data: { status: 'Delivered' },
dismissalPolicy: 'after',
dismissAfter: Date.now() + 3600000 // 1 hour from now
});

Alle aktuell aktiven Live Activities abrufen.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activities } = await CapgoLiveActivities.getAllActivities();
activities.forEach(activity => {
console.log(`Activity ${activity.activityId}: ${activity.state}`);
});

Speichert ein Bild im gemeinsamen App-Group-Container für die Verwendung in Live Activities. Bilder müssen im gemeinsamen Container gespeichert werden, damit die Widget Extension darauf zugreifen kann.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success, imageName } = await CapgoLiveActivities.saveImage({
imageData: 'base64EncodedImageData...',
name: 'product-image',
compressionQuality: 0.8
});
// Use in layout with: { type: 'image', source: 'saved', value: imageName }

Entfernt ein gespeichertes Bild aus dem gemeinsamen Container.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success } = await CapgoLiveActivities.removeImage({ name: 'product-image' });

Listet alle im gemeinsamen Container gespeicherten Bilder auf.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { images } = await CapgoLiveActivities.listImages();
console.log('Saved images:', images);

Entfernt alle gespeicherten Bilder aus dem gemeinsamen Container.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.cleanupImages();

Starte eine Timer-Sequenz für Workouts/Sport. Auf iOS: Wird in der Live Activity und der Dynamic Island angezeigt Auf Android: Wird als Foreground-Notification mit Timer angezeigt

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { sequenceId } = await CapgoLiveActivities.startTimerSequence({
title: 'HIIT Workout',
steps: [
{ duration: 30, title: 'Jumping Jacks', subtitle: 'Warm up', color: '#FF6B00', icon: 'figure.jumprope' },
{ duration: 10, title: 'Rest', color: '#00C853', icon: 'pause.circle' },
{ duration: 45, title: 'Burpees', subtitle: 'High intensity', color: '#FF0000', icon: 'flame.fill' },
{ duration: 15, title: 'Rest', color: '#00C853', icon: 'pause.circle' },
{ duration: 45, title: 'Mountain Climbers', color: '#FF0000', icon: 'figure.run' },
{ duration: 15, title: 'Rest', color: '#00C853', icon: 'pause.circle' },
],
loop: true,
loopCount: 3,
soundEnabled: true,
vibrateEnabled: true,
countdownBeeps: true,
tapUrl: 'myapp://workout/hiit'
});

Pausiere die Timer-Sequenz.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.pauseTimerSequence({ sequenceId: 'abc123' });

Setze eine pausierte Timer-Sequenz fort.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.resumeTimerSequence({ sequenceId: 'abc123' });

Stoppe und schließe die Timer-Sequenz.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.stopTimerSequence({ sequenceId: 'abc123' });

Springt zum nächsten Schritt in der Sequenz.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.skipTimerStep({ sequenceId: 'abc123' });

Gehe zum vorherigen Schritt der Sequenz zurück.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.previousTimerStep({ sequenceId: 'abc123' });

Rufe den aktuellen Status einer Timer-Sequenz ab.

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const state = await CapgoLiveActivities.getTimerState({ sequenceId: 'abc123' });
console.log(`Step ${state.currentStepIndex + 1}/${state.totalSteps}: ${state.currentStep.title}`);
console.log(`Time remaining: ${state.remainingSeconds}s`);

Ergebnis der Prüfung, ob Activities unterstützt werden.

export interface AreActivitiesSupportedResult {
/** Whether Live Activities are supported on this device */
supported: boolean;
/** Reason if not supported */
reason?: string;
}

Optionen zum Starten einer Live Activity.

export interface StartActivityOptions {
/** Main activity layout (lock screen widget) */
layout: ActivityLayout;
/** Dynamic Island layout configuration */
dynamicIslandLayout: DynamicIslandLayout;
/** Activity behavior settings */
behavior?: LiveActivitiesBehavior;
/** Dynamic data for the activity */
data: Record<string, unknown>;
/** Stale date timestamp (activity becomes stale after this) */
staleDate?: number;
/** Relevance score for activity ordering (0-100) */
relevanceScore?: number;
}

Ergebnis beim Starten einer Activity.

export interface StartActivityResult {
/** Unique activity identifier */
activityId: string;
}

Optionen zum Aktualisieren einer Live Activity.

export interface UpdateActivityOptions {
/** Activity ID to update */
activityId: string;
/** Updated data */
data: Record<string, unknown>;
/** Optional alert to show with update */
alertConfiguration?: ActivityAlertConfiguration;
/** Updated stale date */
staleDate?: number;
/** Updated relevance score */
relevanceScore?: number;
}

Optionen zum Beenden einer Live Activity.

export interface EndActivityOptions {
/** Activity ID to end */
activityId: string;
/** Final data to display */
data?: Record<string, unknown>;
/** Dismissal policy */
dismissalPolicy?: 'immediate' | 'default' | 'after';
/** Dismiss after timestamp (when dismissalPolicy is 'after') */
dismissAfter?: number;
}

Ergebnis von getAllActivities.

export interface GetAllActivitiesResult {
/** List of activities */
activities: ActivityInfo[];
}

Optionen zum Speichern eines Bildes.

export interface SaveImageOptions {
/** Base64 encoded image data */
imageData: string;
/** Name to save the image as */
name: string;
/** JPEG compression quality (0-1, default 0.8) */
compressionQuality?: number;
}

Ergebnis des Speicherns eines Bildes.

export interface SaveImageResult {
/** Whether the save was successful */
success: boolean;
/** Saved image name */
imageName: string;
}

Optionen zum Entfernen eines Bildes.

export interface RemoveImageOptions {
/** Name of the image to remove */
name: string;
}

Ergebnis beim Entfernen eines Bildes.

export interface RemoveImageResult {
/** Whether the removal was successful */
success: boolean;
}

Ergebnis beim Auflisten von Bildern.

export interface ListImagesResult {
/** List of saved image names */
images: string[];
}

Optionen zum Starten einer Timer-Sequenz.

export interface TimerSequenceOptions {
/** Array of steps in the sequence */
steps: TimerStep[];
/** Overall title for the sequence (e.g., "HIIT Workout", "Tabata") */
title?: string;
/** Whether to loop the sequence when complete */
loop?: boolean;
/** Number of times to loop (if loop is true, 0 means infinite) */
loopCount?: number;
/** Play sound on step change (default: true) */
soundEnabled?: boolean;
/** Vibrate on step change (default: true) */
vibrateEnabled?: boolean;
/** Play countdown beeps in last 3 seconds (default: true) */
countdownBeeps?: boolean;
/** Deep link URL when tapping the notification/activity */
tapUrl?: string;
/** Keep screen on during timer (Android only, default: false) */
keepScreenOn?: boolean;
}

Diese Seite wird aus dem Plugin generiert src/definitions.ts. Führe den Sync erneut aus, wenn sich das öffentliche API upstream ändert.

Wenn du es nutzt Erste Schritte um Dashboard- und API-Operationen zu planen, verbinde es mit @capgo/capacitor-live-activities verwenden für die native Funktion in „@capgo/capacitor-live-activities verwenden“, API Übersicht für Details zur Implementierung im API Overview, Einführung für die Implementierungsdetails in der Einleitung, API Schlüssel für das Implementierungsdetail in API Keys und Geräte für das Implementierungsdetail in Devices.