Per iniziare
Copia un prompt di configurazione con i passaggi di installazione e la guida markdown completa per questo plugin.
Set up this Capacitor plugin in the project.
Use the package manager already used by the project.
Install these package(s): `@capgo/capacitor-live-activities`
Run the required Capacitor sync/update step after installation.
Read this markdown guide for the full setup steps: https://raw.githubusercontent.com/Cap-go/website/refs/heads/main/apps/docs/src/content/docs/docs/plugins/live-activities/getting-started.mdx
Use that guide for platform-specific steps, native file edits, permissions, config changes, imports, and usage setup.
If that guide references other docs pages, read them too.
Puoi usare il nostro setup assistito dall'IA per installare il plugin. Aggiungi le skill Capgo al tuo strumento di IA usando il seguente comando:
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-pluginsPoi usa il seguente prompt:
Use the `capacitor-plugins` skill from `Cap-go/capgo-skills` to install the `@capgo/capacitor-live-activities` plugin in my project.Se preferisci la configurazione manuale, installa il plugin eseguendo questi comandi e segui le istruzioni specifiche per piattaforma qui sotto:
bun add @capgo/capacitor-live-activitiesbunx cap syncSetup iOS
Sezione: “Configurazione iOS”L'installazione e la sincronizzazione del plugin non creano l'interfaccia nativa della Live Activity. ActivityKit richiede una Widget Extension che registri una configurazione Live Activity prima che startActivity possa visualizzare qualsiasi contenuto.
Requisiti
Sezione intitolata “Requisiti”- Usa iOS 16.1 o versioni successive sia per il target dell'app che per quello della Widget Extension.
- Testa su un dispositivo iOS o un simulatore compatibile. La Dynamic Island appare solo sui modelli supportati; altri dispositivi mostrano la Live Activity sulla Lock Screen.
- Mantieni i dati combinati (statici e dinamici) di ActivityKit entro il limite di 4 KB di Apple.
1. Crea una Widget Extension
Sezione intitolata “1. Crea una Widget Extension”Apri il progetto nativo iOS:
bunx cap open iosPoi:
- Seleziona File > Nuovo > Target.
- Aggiungi un Widget Extension.
- Abilita Includi Live Activity.
- Disable Includi l'Intent di configurazione a meno che l'app non richieda anche un widget configurabile.
- Assicurati che l'estensione generata sia incorporata nel target dell'app principale.
La Widget Extension deve contenere un ActivityConfiguration e registrarlo nel suo WidgetBundle. Deve fornire ogni Live Activity presentation richiesta:
- Schermata di blocco
- Dynamic Island espansa
- Dynamic Island compact leading e trailing
- Dynamic Island minimale
Aggiungere solo il target non è sufficiente. L'app nativa o il plugin devono chiamare le API request, update ed end di ActivityKit. L'estensione deve contenere code in SwiftUI in grado di decodificare e renderizzare lo stesso ActivityAttributes e lo stato del contenuto usati da tali chiamate. Includi i modelli ActivityKit condivisi sia nel target dell'app principale che in quello della Widget Extension. Il template Live Activity generato da Xcode non renderizza automaticamente i layout JSON passati a questo plugin; l'estensione necessita anche di un renderer nativo compatibile.
2. Abilita le Live Activities
Sezione: “2. Abilitare le Live Activities”Aggiungi la seguente chiave al target principale dell'app: Info.plist:
<key>NSSupportsLiveActivities</key><true/>Se il progetto genera il proprio Info.plist, aggiungi Supporta Live Activities con un valore Boolean di YES sotto le proprietà custom del target iOS dell'app principale.
3. Configura l'App Group per le immagini condivise
Sezione: “3. Configurare l'App Group per le immagini condivise”Un App Group è necessario solo quando si usa saveImage, removeImage, listImages, o cleanupImages. Il plugin deriva l'App Group identifier dal bundle identifier dell'app principale usando questo formato:
group.<MAIN_APP_BUNDLE_ID>.liveactivitiesAd esempio, un'app con bundle identifier com.example.delivery deve usare:
group.com.example.delivery.liveactivitiesIn Xcode, aggiungi la App Groups capability sia al target dell'app principale che al target della Widget Extension, quindi abilita lo stesso identifier su entrambi i target.
Le estensioni Live Activity non possono accedere alla rete. Scarica le immagini remote nell'app principale e salvale nell'App Group condiviso prima di richiamarle da una Live Activity. Per le immagini incluse nel bundle, abilita la Widget Extension anche nella target membership dell'asset.
4. Configura i Deep Link
Sezione intitolata “4. Configure Deep Links”Quando usi behavior.widgetUrl o una sequenza di timer tapUrl, registra lo scheme URL o l'Universal Link corrispondente nell'app principale. Per uno scheme personalizzato come myapp://order/12345, aggiungi lo scheme nelle impostazioni Info > Tipi di URL settings.
5. Opzionale: abilita gli aggiornamenti server-driven
Sezione: “5. Opzionale: Abilita gli aggiornamenti server-driven”Le notifiche push non sono necessarie per gli aggiornamenti locali avviati dall'app. Per avviare, aggiornare o terminare le Live Activities da un server:
- Aggiungi la Notifiche push capability al target dell'app principale.
- Ottieni i token push di ActivityKit e inviali al server.
- Invia notifiche ActivityKit tramite APNs usando il
liveactivitytipo push. - Aggiungi
NSSupportsLiveActivitiesFrequentUpdatesall'app principaleInfo.plistsolo quando il caso d'uso richiede aggiornamenti push frequenti.
I token push di ActivityKit sono distinti dai token standard per le notifiche utente. Abilitare solo la capability Push Notifications non è sufficiente; gli aggiornamenti lato server richiedono la gestione dei token nativi e un backend APNs.
Checklist per il setup nativo
Sezione intitolata “Native Setup Checklist”Prima di chiamare startActivity, verifica che:
NSSupportsLiveActivitiessia abilitato sul target dell'app principale.- La Widget Extension è incorporata e registra un
ActivityConfiguration. - L'implementazione nativa di ActivityKit e la Widget Extension usano lo stesso
ActivityAttributestipo. - I deployment target dell'app e della Widget Extension sono iOS 16.1 o successivi.
- Le Live Activities sono abilitate per l'app nelle Impostazioni di iOS.
- L'App Group corrispondente è abilitato su entrambi i target quando si usano immagini condivise.
- Qualsiasi custom URL scheme utilizzato da
widgetUrlotapUrlviene registrato.
Importa
Sezione intitolata “Import”import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';Avvio rapido
Sezione intitolata “Quick start”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);}Esempio: startActivity
Sezione intitolata “Esempio: startActivity”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);Esempio: updateActivity
Sezione intitolata “Esempio: updateActivity”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!' }});Errori comuni
Sezione intitolata “Errori comuni”- Listener: rimuovi gli handle quando gli schermi vengono smontati.
- Sync nativo: esegui
bunx cap syncdopo gli aggiornamenti dei plugin. - Fonte di verità: fidati
src/definitions.tsnel repo GitHub.
Panoramica API
Sezione intitolata “Panoramica API”areActivitiesSupported
Sezione intitolata “areActivitiesSupported”Verifica se le Live Activities sono supportate su questo dispositivo. Richiede iOS 16.1+ e supporto del dispositivo.
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);}startActivity
Sezione intitolata “startActivity”Avvia una nuova Live Activity con il layout e i dati specificati.
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);updateActivity
Sezione intitolata “updateActivity”Aggiorna una Live Activity esistente con nuovi dati.
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!' }});endActivity
Sezione intitolata “endActivity”Termina una Live Activity.
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});getAllActivities
Sezione intitolata “getAllActivities”Recupera tutte le Live Activity attualmente attive.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activities } = await CapgoLiveActivities.getAllActivities();activities.forEach(activity => { console.log(`Activity ${activity.activityId}: ${activity.state}`);});saveImage
Sezione intitolata “saveImage”Salva un'immagine nel container condiviso dell'App Group per usarla nelle Live Activities. Le immagini devono essere salvate nel container condiviso per essere accessibili dall'estensione del widget.
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 }removeImage
Sezione intitolata “removeImage”Rimuovi un'immagine salvata dal container condiviso.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success } = await CapgoLiveActivities.removeImage({ name: 'product-image' });listImages
Sezione intitolata “listImages”Elenca tutte le immagini salvate nel container condiviso.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { images } = await CapgoLiveActivities.listImages();console.log('Saved images:', images);cleanupImages
Sezione intitolata “cleanupImages”Rimuovi tutte le immagini salvate dal container condiviso.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.cleanupImages();startTimerSequence
Sezione intitolata “startTimerSequence”Avvia una sequenza timer per allenamenti o sport. Su iOS: appare in Live Activity e Dynamic Island Su Android: appare come notifica in primo piano con timer
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'});pauseTimerSequence
Sezione intitolata “pauseTimerSequence”Mette in pausa la sequenza timer.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.pauseTimerSequence({ sequenceId: 'abc123' });resumeTimerSequence
Sezione intitolata “resumeTimerSequence”Riprende una sequenza timer in pausa.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.resumeTimerSequence({ sequenceId: 'abc123' });stopTimerSequence
Sezione intitolata “stopTimerSequence”Ferma e chiude la sequenza timer.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.stopTimerSequence({ sequenceId: 'abc123' });skipTimerStep
Sezione intitolata “skipTimerStep”Salta al passaggio successivo della sequenza.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.skipTimerStep({ sequenceId: 'abc123' });previousTimerStep
Sezione intitolata “previousTimerStep”Torna al passaggio precedente della sequenza.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.previousTimerStep({ sequenceId: 'abc123' });getTimerState
Sezione intitolata “getTimerState”Ottieni lo stato attuale di una sequenza timer.
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`);Riferimento ai tipi
Sezione: “Type Reference”AreActivitiesSupportedResult
Sezione intitolata “AreActivitiesSupportedResult”Risultato del controllo sul supporto delle attività.
export interface AreActivitiesSupportedResult { /** Whether Live Activities are supported on this device */ supported: boolean; /** Reason if not supported */ reason?: string;}StartActivityOptions
Sezione intitolata “StartActivityOptions”Opzioni per avviare una 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;}StartActivityResult
Sezione intitolata “StartActivityResult”Risultato dell'avvio di un'attività.
export interface StartActivityResult { /** Unique activity identifier */ activityId: string;}UpdateActivityOptions
Sezione intitolata “UpdateActivityOptions”Opzioni per aggiornare una 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;}EndActivityOptions
Sezione intitolata “EndActivityOptions”Opzioni per terminare una 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;}GetAllActivitiesResult
Sezione intitolata “GetAllActivitiesResult”Risultato di getAllActivities.
export interface GetAllActivitiesResult { /** List of activities */ activities: ActivityInfo[];}SaveImageOptions
Sezione intitolata “SaveImageOptions”Opzioni per il salvataggio di un'immagine.
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;}SaveImageResult
Sezione intitolata “SaveImageResult”Risultato del salvataggio di un'immagine.
export interface SaveImageResult { /** Whether the save was successful */ success: boolean; /** Saved image name */ imageName: string;}RemoveImageOptions
Sezione intitolata “RemoveImageOptions”Opzioni per rimuovere un'immagine.
export interface RemoveImageOptions { /** Name of the image to remove */ name: string;}RemoveImageResult
Sezione intitolata “RemoveImageResult”Risultato della rimozione di un'immagine.
export interface RemoveImageResult { /** Whether the removal was successful */ success: boolean;}ListImagesResult
Sezione intitolata “ListImagesResult”Risultato dell'elenco delle immagini.
export interface ListImagesResult { /** List of saved image names */ images: string[];}TimerSequenceOptions
Sezione intitolata “TimerSequenceOptions”Opzioni per avviare una sequenza timer.
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;}Fonte di verità
Sezione intitolata “Fonte di verità”Questa pagina è generata dal src/definitions.ts. Riesegui la sync quando il API pubblico cambia upstream.
Continua da Getting Started
Sezione intitolata “Continua da Getting Started”Se stai usando Per iniziare per pianificare le operazioni della dashboard e di API, collegalo a Uso di @capgo/capacitor-live-activities per la funzionalità nativa nella pagina Uso di @capgo/capacitor-live-activities, Panoramica API per i dettagli di implementazione in Panoramica di API, Introduzione per i dettagli di implementazione in Introduzione, Chiavi API per i dettagli di implementazione in Chiavi API, e Dispositivi per i dettagli di implementazione in Dispositivi.