시작하기
이 플러그인의 설치 단계와 전체 마크다운 가이드가 포함된 설정 프롬프트를 복사하세요.
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.
AI-Assisted Setup으로 플러그인을 설치할 수 있습니다. 다음 명령어로 AI 도구에 Capgo 스킬을 추가하세요:
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins그런 다음 아래 프롬프트를 사용하세요:
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-activitiesbunx cap synciOS 설정
“iOS Setup” 섹션플러그인을 설치하고 동기화한다고 해서 native Live Activity UI가 바로 생성되지는 않습니다. ActivityKit은 화면에 내용을 표시하기 전에 Live Activity 설정을 등록하는 Widget Extension이 반드시 필요합니다. startActivity 내용을 표시하려면 다음 단계를 진행하세요.
요구 사항
“요구 사항” 섹션- 앱 타겟과 Widget Extension 타겟 모두 iOS 16.1 이상 버전을 사용해야 합니다.
- iOS 기기 또는 호환되는 시뮬레이터에서 테스트하세요. Dynamic Island는 지원되는 모델에서만 나타나며, 그 외 기기에서는 Lock Screen 방식으로 표시됩니다.
- 정적 및 동적 ActivityKit 데이터의 합계가 Apple의 4 KB 제한을 넘지 않도록 주의하세요.
1. Widget Extension 생성
“1. Widget Extension 생성하기” 섹션iOS 네이티브 프로젝트를 엽니다:
bunx cap open ios그 다음:
- 선택 파일 > 새로 만들기 > 타겟.
- 다음 Widget Extension.
- 활성화 Include Live Activity를 활성화하세요..
- 비활성화 Configuration Intent 포함하기 앱에 설정 가능한 위젯이 필요한 경우가 아니라면 생략해도 됩니다.
- 생성된 extension이 메인 앱 타겟에 포함되었는지 확인하세요.
Widget Extension에는 반드시 다음이 포함되어야 합니다: ActivityConfiguration 및 이를 해당 위치에 등록해야 합니다. WidgetBundle. 모든 필수 Live Activity 프리젠테이션을 제공해야 합니다:
- 잠금 화면
- Dynamic Island 확장형
- Dynamic Island 컴팩트 (Leading/Trailing)
- Dynamic Island 미니멀
타겟만 추가하는 것으로는 부족합니다. 네이티브 앱이나 플러그인에서 ActivityKit의 request, update, end API를 호출해야 합니다. 또한 extension에는 해당 호출에서 사용하는 code 및 content state를 디코딩하고 렌더링할 수 있는 SwiftUI 코드가 포함되어야 합니다. ActivityAttributes 메인 앱과 Widget Extension 타겟 모두에 공유 ActivityKit 모델을 포함하세요. Xcode에서 생성된 Live Activity 템플릿은 이 플러그인에 전달된 JSON 레이아웃을 자동으로 렌더링하지 않으므로, extension에도 호환되는 네이티브 레이아웃 렌더러가 필요합니다.
2. Live Activities 활성화하기
“2. Live Activities 활성화하기” 섹션메인 앱 타겟에 다음 키를 추가하세요: Info.plist:
<key>NSSupportsLiveActivities</key><true/>프로젝트에서 다음을 생성하는 경우 Info.plist, 다음을 추가하세요 Live Activities 지원 Boolean 값으로 YES 대신 메인 앱 타겟의 커스텀 iOS 타겟 속성에 추가하세요.
3. 이미지 공유를 위한 App Group 설정
“3. 이미지 공유를 위한 App Group 설정” 섹션App Group은 다음을 사용할 때만 필요합니다: saveImage, removeImage, listImages, 또는 cleanupImages. 이 플러그인은 다음 정확한 형식으로 메인 앱 bundle identifier에서 App Group identifier를 도출합니다:
group.<MAIN_APP_BUNDLE_ID>.liveactivities예를 들어, bundle identifier가 com.example.delivery must use:
group.com.example.delivery.liveactivitiesXcode에서 다음을 추가하세요: App Groups capability를 메인 앱 타겟과 Widget Extension 타겟 모두에 추가한 다음, 두 타겟에서 동일한 identifier를 활성화하세요.
Live Activity extension은 네트워크에 접속할 수 없습니다. 원격 이미지는 Live Activity에서 참조하기 전에 메인 앱에서 다운로드하여 공유 App Group에 저장하세요. 번들 이미지의 경우 asset의 target membership에서 Widget Extension도 활성화해야 합니다.
4. Deep Links 설정
“4. Deep Links 설정” 섹션사용 시 behavior.widgetUrl 또는 타이머 시퀀스를 tapUrl, 메인 앱에 일치하는 URL scheme 또는 Universal Link를 등록하세요. 다음 예시와 같은 커스텀 scheme의 경우, myapp://order/12345, 메인 앱 타겟의 Info > URL Types 항목에 scheme을 추가하세요. 설정에서.
5. 선택 사항: Server-Driven Updates 활성화
“5. 선택 사항: Server-Driven Updates 활성화” 섹션앱에서 시작하는 로컬 업데이트에는 Push Notifications가 필요하지 않습니다. 서버에서 Live Activities를 시작, 업데이트 또는 종료하려면:
- 다음을 추가하세요 푸시 알림 기능을 메인 앱 타겟에 추가하세요.
- ActivityKit push token을 가져와 서버로 전송합니다.
- APNs를 통해 ActivityKit 알림을 전송하려면
liveactivitypush 타입을 사용하세요. - 추가
NSSupportsLiveActivitiesFrequentUpdates메인 앱으로Info.plist사용 사례에서 빈번한 push 업데이트가 필요할 때만 사용하세요.
ActivityKit push token은 표준 사용자 알림 디바이스 token과 별개입니다. Push Notifications capability만 활성화해서는 충분하지 않으며, 서버 기반 업데이트에는 네이티브 token 처리와 APNs 백엔드가 필요합니다.
Native 설정 체크리스트
“Native 설정 체크리스트” 섹션호출하기 전에 startActivity, 다음을 확인하세요:
NSSupportsLiveActivities가 메인 앱 타겟에서 활성화되어 있는지.- Widget Extension이 포함되어 있으며 다음을 등록합니다:
ActivityConfiguration. - 네이티브 ActivityKit 구현체와 Widget Extension은 동일한
ActivityAttributes타입을 사용합니다. - 앱과 Widget Extension의 배포 타깃은 iOS 16.1 이상이어야 합니다.
- iOS 설정에서 앱의 Live Activities가 활성화되어 있어야 합니다.
- 이미지를 공유하는 경우 두 타깃 모두에서 동일한 App Group이 활성화되어 있어야 합니다.
- 사용하는 모든 커스텀 URL scheme은
widgetUrl또는tapUrl등록되어 있어야 합니다.
가져오기
“Import” 섹션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);}예시: startActivity
“예시: 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);예시: updateActivity
“예시: 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!' }});자주 하는 실수
“흔한 실수” 섹션- 리스너: 화면이 언마운트될 때 핸들을 제거합니다.
- 네이티브 동기화: 실행
bunx cap sync플러그인 업그레이드 후. - 신뢰할 수 있는 소스: 신뢰
src/definitions.tsGitHub 레포지토리에서.
API 개요
“API 개요” 섹션areActivitiesSupported
“areActivitiesSupported” 섹션이 기기에서 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);}startActivity
“startActivity” 섹션지정된 레이아웃과 데이터로 새로운 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);updateActivity
“updateActivity” 섹션기존 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!' }});endActivity
“endActivity” 섹션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
“getAllActivities” 섹션현재 활성화된 모든 Live Activity를 가져옵니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activities } = await CapgoLiveActivities.getAllActivities();activities.forEach(activity => { console.log(`Activity ${activity.activityId}: ${activity.state}`);});saveImage
“saveImage” 섹션Live Activities에서 사용할 이미지를 공유 App Group 컨테이너에 저장합니다. 위젯 익스텐션에서 이미지에 접근하려면 반드시 공유 컨테이너에 저장해야 합니다.
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
“removeImage” 섹션저장된 이미지를 공유 컨테이너에서 삭제합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success } = await CapgoLiveActivities.removeImage({ name: 'product-image' });listImages
“listImages” 섹션공유 컨테이너에 저장된 모든 이미지를 나열합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { images } = await CapgoLiveActivities.listImages();console.log('Saved images:', images);cleanupImages
“cleanupImages” 섹션공유 컨테이너에 저장된 모든 이미지를 삭제합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.cleanupImages();startTimerSequence
“startTimerSequence” 섹션운동/스포츠용 타이머 시퀀스를 시작합니다. 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'});pauseTimerSequence
“pauseTimerSequence” 섹션타이머 시퀀스를 일시 중지합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.pauseTimerSequence({ sequenceId: 'abc123' });resumeTimerSequence
“resumeTimerSequence” 섹션일시 중지된 타이머 시퀀스를 재개합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.resumeTimerSequence({ sequenceId: 'abc123' });stopTimerSequence
“stopTimerSequence” 섹션타이머 시퀀스를 중지하고 해제합니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.stopTimerSequence({ sequenceId: 'abc123' });skipTimerStep
“skipTimerStep” 섹션시퀀스의 다음 단계로 건너뜁니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.skipTimerStep({ sequenceId: 'abc123' });previousTimerStep
“previousTimerStep” 섹션시퀀스의 이전 단계로 돌아갑니다.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.previousTimerStep({ sequenceId: 'abc123' });getTimerState
“getTimerState” 섹션타이머 시퀀스의 현재 상태를 가져옵니다.
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” 섹션Activity 지원 여부 확인 결과.
export interface AreActivitiesSupportedResult { /** Whether Live Activities are supported on this device */ supported: boolean; /** Reason if not supported */ reason?: string;}StartActivityOptions
“StartActivityOptions” 섹션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
“StartActivityResult” 섹션Activity 시작 결과.
export interface StartActivityResult { /** Unique activity identifier */ activityId: string;}UpdateActivityOptions
“UpdateActivityOptions” 섹션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
“EndActivityOptions” 섹션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
“GetAllActivitiesResult” 섹션getAllActivities의 결과값입니다.
export interface GetAllActivitiesResult { /** List of activities */ activities: ActivityInfo[];}SaveImageOptions
“SaveImageOptions” 섹션이미지를 저장하기 위한 옵션입니다.
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
“SaveImageResult” 섹션이미지 저장 결과값입니다.
export interface SaveImageResult { /** Whether the save was successful */ success: boolean; /** Saved image name */ imageName: string;}RemoveImageOptions
“RemoveImageOptions” 섹션이미지 삭제 옵션.
export interface RemoveImageOptions { /** Name of the image to remove */ name: string;}RemoveImageResult
“RemoveImageResult” 섹션이미지 삭제 결과.
export interface RemoveImageResult { /** Whether the removal was successful */ success: boolean;}ListImagesResult
“ListImagesResult” 섹션이미지 목록 조회 결과.
export interface ListImagesResult { /** List of saved image names */ images: string[];}TimerSequenceOptions
“TimerSequenceOptions” 섹션타이머 시퀀스 시작 옵션.
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;}Source of Truth
“Source Of Truth” 섹션이 페이지는 플러그인의 src/definitions.tsupstream에서 public API가 변경되면 sync를 다시 실행하세요.
시작하기 다음 단계
“Getting Started에서 계속하기” 섹션사용 중이라면 시작하기 대시보드 및 API 운영을 계획하려면, 이를 다음과 연결하세요 @capgo/capacitor-live-activities 사용 @capgo/capacitor-live-activities 사용에서의 네이티브 기능, API 개요 구현 세부 사항은 API 개요에서 소개 구현 세부 사항은 소개에서 API 키 API Keys의 구현 세부 사항은, 기기 Devices의 구현 세부 사항은.