跳转到正文

快速入门

GitHub

你可以使用我们的 AI 辅助设置来安装插件。使用以下命令将 Capgo skills 添加到你的 AI 工具中:

终端窗口
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins

然后使用以下 prompt:

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

如果你更想手动设置,请运行以下命令安装插件,并按照下方各平台的说明操作:

终端窗口
bun add @capgo/capacitor-live-activities
bunx cap sync

仅安装并同步插件并不会创建原生的 Live Activity UI。ActivityKit 要求在显示内容之前,必须先通过 Widget Extension 注册 Live Activity 配置, startActivity 然后才能进行展示。

  • 请确保 App target 和 Widget Extension target 均使用 iOS 16.1 或更高版本。
  • 请在 iOS 真机或兼容的模拟器上进行测试。Dynamic Island 仅在支持的机型上显示;其他设备将以锁屏界面形式呈现。
  • 请确保 ActivityKit 的静态与动态数据总量保持在 Apple 规定的 4 KB 限制之内。

1. 创建 Widget Extension

“1. 创建 Widget Extension”章节

打开 iOS 原生项目:

终端窗口
bunx cap open ios

然后:

  1. 选择 文件 > 新建 > Target.
  2. 添加一个 小组件扩展 (Widget Extension).
  3. 启用 包含 Live Activity.
  4. Disable 包含配置意图 除非应用还需要可配置的 Widget。
  5. 确保生成的 Extension 已嵌入到主 App Target 中。

Widget Extension 必须包含一个 ActivityConfiguration and register it in its WidgetBundle它必须提供所有必需的 Live Activity 展示形式:

  • 锁定屏幕
  • Dynamic Island 展开状态
  • Dynamic Island 紧凑状态(前置与后置)
  • Dynamic Island 最小状态

仅添加 Target 是不够的。原生 App 或插件必须调用 ActivityKit 的 request、update 和 end API。Extension 必须包含能够解码并渲染与这些调用所使用的相同的 code 和内容状态的 SwiftUI 代码。请在主 App 和 Widget Extension Target 中都包含共享的 ActivityKit 模型。Xcode 生成的 Live Activity 模板不会自动渲染传递给此插件的 JSON 布局;Extension 也需要一个兼容的原生布局渲染器。 ActivityAttributes and content state used by those calls. Include shared ActivityKit models in both the main app and Widget Extension targets. The Xcode-generated Live Activity template does not automatically render the JSON layouts passed to this plugin; the extension also needs a compatible native layout renderer.

2. 启用 Live Activities

“2. 启用 Live Activities”章节

在主 App target 中添加以下键值: Info.plist:

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

如果项目生成了其 Info.plist,添加 支持 Live Activities 并将布尔值设为 YES ,而是将其添加到主 App target 的自定义 iOS target 属性下。

仅在以下情况需要使用 App Group: saveImage, removeImage, listImages,或 cleanupImages该插件会按照以下格式,从主 App 的 bundle identifier 中推导出 App Group 标识符:

group.<MAIN_APP_BUNDLE_ID>.liveactivities

例如,对于 bundle identifier 为 com.example.delivery 的 App,必须使用:

group.com.example.delivery.liveactivities

在 Xcode 中,请为 App 主 target 和 Widget Extension target 都添加 App Groups capability,并在两个 target 中启用相同的标识符。

Live Activity extension 无法访问网络。请先在主 App 中下载远程图片,并将其保存到共享的 App Group 中,然后再在 Live Activity 中引用。对于 bundle 中的图片,还需在 asset 的 target membership 中勾选 Widget Extension。

使用 behavior.widgetUrl 或定时器序列时 tapUrl,请在主 App 中注册匹配的 URL Scheme 或 Universal Link。对于像 myapp://order/12345这样的自定义 Scheme,请在主 App Target 的 信息 > URL 类型 设置中添加该 Scheme。

由 App 发起的本地更新不需要推送通知。若要从服务端启动、更新或结束 Live Activities:

  • 添加 推送通知 将该能力添加到主 App Target。
  • 获取 ActivityKit push tokens 并将其发送至服务器。
  • 通过 APNs 使用 liveactivity 推送类型。
  • 添加 NSSupportsLiveActivitiesFrequentUpdates 仅在业务场景需要频繁推送更新时, Info.plist 才向主 App 发送。

ActivityKit push tokens 与标准的通知设备 token 是分开的。 仅开启 Push Notifications 能力是不够的;服务端驱动的更新需要原生 token 处理和 APNs 后端支持。

在调用 startActivity之前,请确认:

  • NSSupportsLiveActivities 已在主 App target 上启用。
  • Widget Extension 已嵌入并注册了 ActivityConfiguration.
  • 原生 ActivityKit 实现与 Widget Extension 使用相同的 ActivityAttributes 类型。
  • App 与 Widget Extension 的部署目标均为 iOS 16.1 或更高版本。
  • 该 App 已在 iOS 设置中启用 Live Activities。
  • 使用共享图片时,两个 target 上需启用匹配的 App Group。
  • 任何由以下项使用的自定义 URL scheme widgetUrl 或 tapUrl 均已注册。
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!'
}
});
  • 监听器: 在页面卸载时移除句柄。
  • 原生同步:运行 bunx cap sync 在插件升级后。
  • 唯一可信来源:信任 src/definitions.ts 在 GitHub 仓库中。

检查此设备是否支持 Live Activities。 需要 iOS 16.1+ 及设备硬件支持。

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

使用指定的布局和数据启动新的 Live Activity。

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

使用新数据更新现有的 Live Activity。

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

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

获取所有当前活跃的 Live Activities。

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

将图片保存到共享 App Group 容器中,以便在 Live Activities 中使用。 图片必须保存到共享容器,才能被 widget extension 访问。

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 }

从共享容器中移除已保存的图片。

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

列出共享容器中所有已保存的图片。

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

从共享容器中移除所有已保存的图片。

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

启动健身/运动计时序列。 iOS 端:显示在 Live Activity 和 Dynamic Island 中 Android 端:以带有计时器的前台通知形式显示

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

暂停计时器序列。

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

恢复已暂停的计时器序列。

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

停止并关闭计时器序列。

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

跳到序列中的下一步。

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

返回序列中的上一步。

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

获取计时器序列的当前状态。

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

AreActivitiesSupportedResult

“AreActivitiesSupportedResult” 章节

检查是否支持 Live Activity 的结果。

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

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

启动 Activity 的结果。

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

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

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

getAllActivities 的结果。

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

保存图片的选项。

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

保存图片的结果。

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

移除图片的选项。

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

移除图片的结果。

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

列出图片的结果。

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

启动计时器序列的选项。

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

本页面由插件的 src/definitions.ts生成。当上游的公共 API 发生变化时,请重新运行 sync。

如果你正在使用 快速入门 要规划 dashboard 和 API 操作,请将其连接到 使用 @capgo/capacitor-live-activities 用于使用 @capgo/capacitor-live-activities 时的原生能力, API 概览 关于 API Overview 中的实现细节, 简介 关于 Introduction 中的实现细节, API 密钥 有关 API Keys 的实现细节,以及 设备 有关 Devices 的实现细节。