Saltar al contenido

Getting Started

GitHub

Puede utilizar nuestra configuración asistida por IA para instalar el plugin. Agregue las Capgo habilidades a su herramienta de IA utilizando el siguiente comando:

Ventana de terminal
npx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins

Luego utilice el siguiente prompt:

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

Si prefieres Instalación Manual, instala el complemento ejecutando los siguientes comandos y sigue las instrucciones específicas de la plataforma a continuación:

Ventana de Terminal
bun add @capgo/capacitor-live-activities
bunx cap sync

La instalación y sincronización del complemento no crean la interfaz de usuario de Actividad en vivo nativa. ActivityKit requiere una Extensión de Widget que registre una configuración de Actividad en vivo antes de startActivity poder mostrar algo.

  • Utiliza iOS 16.1 o posterior para ambas metas del objetivo de la aplicación y la extensión de Widget.
  • Prueba en un dispositivo iOS o un simulador compatible. La Isla Dinámica solo aparece en modelos de dispositivos compatibles; otros dispositivos utilizan la presentación de pantalla de bloqueo.
  • Mantén los datos estáticos y dinámicos combinados de ActivityKit por debajo del límite de 4 KB de Apple.

Abre el proyecto nativo de iOS:

Ventana de Terminal
bunx cap open ios

Luego:

  1. Selecciona Archivo > Nuevo > Objetivo.
  2. Agregar una Extensión de Widget.
  3. Habilita Incluir Actividad en Vivo.
  4. Desactivar Incluir configuración de intención a menos que la aplicación también necesite un widget configurable.
  5. Asegúrese de que la extensión generada esté integrada en el objetivo principal de la aplicación.

La extensión de Widget debe contener un ActivityConfiguration y registrarlo en su WidgetBundle. Debe proporcionar cada presentación de actividad en vivo requerida:

  • Pantalla de bloqueo
  • Dynamic Island ampliado
  • Dynamic Island compacto con leading y trailing
  • Dynamic Island mínimo

Agregar el objetivo solo no es suficiente. La aplicación nativa o el plugin deben llamar a las API de solicitud, actualización y fin de ActivityKit. La extensión debe contener SwiftUI code que pueda descodificar y renderizar lo mismo ActivityAttributes y el estado de contenido utilizado por esas llamadas. Incluya modelos de ActivityKit compartidos en ambos objetivos del app principal y la extensión de Widget. El template de actividad en vivo generado por Xcode no renderiza automáticamente los diseños JSON pasados a este plugin; la extensión también necesita un renderizador de diseños nativos compatible.

Agregar la siguiente clave a las propiedades de objetivo iOS personalizado del app principal: Info.plist:

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

Si el proyecto genera sus Info.plist, agregue Compatibilidad con Actividades en Vivo con un valor booleano de YES bajo las propiedades de objetivo iOS personalizado del app principal en lugar de

3. Configurar el Grupo de Aplicación para Imágenes Compartidas

Título de la sección “3. Configurar el Grupo de Aplicación para Imágenes Compartidas”

Un grupo de aplicaciones solo es necesario cuando se utiliza saveImage, removeImage, listImages, o cleanupImagesEl plugin deriva el identificador del grupo de aplicaciones del identificador del paquete principal de la aplicación utilizando este formato exacto:

group.<MAIN_APP_BUNDLE_ID>.liveactivities

Por ejemplo, una aplicación con identificador de paquete com.example.delivery debe utilizar:

group.com.example.delivery.liveactivities

En Xcode, agregue la capacidad de grupos de aplicaciones a ambos objetivos de la aplicación principal y la extensión de Widget, luego habilite el mismo identificador en ambos objetivos.

Las extensiones de actividad en vivo no pueden acceder a la red. Descargue imágenes remotos en la aplicación principal y guárdelos en el grupo de aplicaciones compartido antes de referenciarlos desde una actividad en vivo. Para imágenes embutidas, también habilite la extensión de Widget en la pertenencia de objetivos del recurso.

Cuando se utilice behavior.widgetUrl o una secuencia de temporizador tapUrl, registre el esquema de URL correspondiente o el enlace Universal en la aplicación principal. Para un esquema personalizado como myapp://order/12345, agregue el esquema bajo la configuración de Info > Tipos de URL del objetivo de la aplicación principal.

5. Opcional: Habilitar actualizaciones impulsadas por servidor

Sección titulada “5. Opcional: Habilitar actualizaciones impulsadas por servidor”

Las notificaciones de push no son necesarias para actualizaciones locales iniciadas por la aplicación. Para comenzar, actualizar o finalizar Actividades en vivo desde un servidor:

  • Agregar el Notificaciones de push capacidad al aplicativo principal objetivo.
  • Obtener tokens de notificación de ActivityKit y enviarlos al servidor.
  • Enviar notificaciones de ActivityKit a través de APNs utilizando el liveactivity tipo de empuje.
  • Agregar NSSupportsLiveActivitiesFrequentUpdates solo al aplicativo principal Info.plist solo cuando el caso de uso requiere actualizaciones de empuje frecuentes.

Los tokens de empuje de ActivityKit están separados de los tokens de notificación estándar del dispositivo del usuario. Habilitar la capacidad de notificaciones de empuje sola no es suficiente; las actualizaciones impulsadas por el servidor requieren un manejo nativo de tokens y un backend de APNs.

Antes de llamar a startActivity, verifique que:

  • NSSupportsLiveActivities está habilitado en la aplicación principal objetivo.
  • La extensión del Widget está integrada y registra un ActivityConfiguration.
  • La implementación nativa de ActivityKit y la extensión del Widget utilizan el mismo ActivityAttributes tipo.
  • La aplicación y los objetivos de despliegue de la extensión del Widget son iOS 16.1 o posterior.
  • Las actividades en vivo están habilitadas para la aplicación en iOS Settings.
  • El grupo de aplicación correspondiente está habilitado en ambos objetivos cuando se utilizan imágenes compartidas.
  • Cualquier esquema de URL personalizado utilizado por widgetUrl o tapUrl se registra.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';

Verificar si las actividades en vivo están soportadas en este dispositivo. Requiere iOS 16.1+ y soporte de 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);
}

Iniciar una nueva actividad en vivo con el diseño especificado y los datos.

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

Actualizar una actividad en vivo existente con nuevos datos.

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

Finalizar una Actividad en vivo.

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

Obtener todas las actividades en vivo actualmente activas.

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

Guardar una imagen en el contenedor compartido de App Group para su uso en Actividades en vivo. Las imágenes deben guardarse en el contenedor compartido para ser accesibles desde la extensión de 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 }

Eliminar una imagen guardada del contenedor compartido.

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

Mostrar todas las imágenes guardadas en el contenedor compartido.

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

Eliminar todas las imágenes guardadas del contenedor compartido.

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

Iniciar una secuencia de temporizador para ejercicios/deportes. En iOS: Muestra en Actividad en vivo y Isla Dinámica En Android: Muestra como una notificación de primer plano con temporizador

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

Pausar la secuencia de temporizador.

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

Reanuda la secuencia de temporizador suspendida.

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

Detener y descartar la secuencia de temporizador.

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

Saltar al siguiente paso en la secuencia.

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

Volver al paso anterior en la secuencia.

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

Obtenga el estado actual de una secuencia de temporizadores.

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

Resultado de verificar si las actividades están soportadas.

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

Opciones para iniciar una actividad en vivo.

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

Resultado de iniciar una actividad.

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

Opciones para actualizar una actividad en vivo.

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

Opciones para finalizar una actividad en vivo.

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

Resultado de obtener todas las actividades.

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

Opciones para guardar una imagen.

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

Resultado de guardar una imagen.

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

Opciones para eliminar una imagen.

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

Resultado de eliminar una imagen.

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

Resultado de la lista de imágenes.

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

Opciones para iniciar una secuencia de temporizador.

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

Esta página se genera desde el plugin’s src/definitions.ts. Re-ejecutar la sincronización cuando el público API cambia en línea.

Si estás utilizando Iniciación para planificar la consola y API operaciones, conecte con Usando @capgo/capacitor-actividades-en-vivo para la capacidad nativa en Usando @capgo/capacitor-actividades-en-vivo Resumen de API para el detalle de implementación en Resumen de API Introducción para el detalle de implementación en Introducción Claves de API para el detalle de implementación en Claves de API y Dispositivos para el detalle de implementación en Dispositivos.