Panduan Memulai
Salin prompt setup yang berisi langkah install dan panduan markdown lengkap untuk plugin ini.
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.
Anda bisa menggunakan AI-Assisted Setup kami untuk menginstal plugin ini. Tambahkan skill Capgo ke tool AI Anda dengan command berikut:
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-pluginsLalu gunakan prompt berikut:
Use the `capacitor-plugins` skill from `Cap-go/capgo-skills` to install the `@capgo/capacitor-live-activities` plugin in my project.Jika Anda lebih memilih Manual Setup, instal plugin dengan menjalankan perintah berikut dan ikuti petunjuk khusus platform di bawah ini:
bun add @capgo/capacitor-live-activitiesbunx cap syncSetup iOS
Bagian berjudul “iOS Setup”Menginstal dan menyinkronkan plugin tidak membuat UI native Live Activity. ActivityKit memerlukan Widget Extension yang mendaftarkan konfigurasi Live Activity sebelum startActivity bisa menampilkan apa pun.
Persyaratan
Bagian berjudul “Persyaratan”- Gunakan iOS 16.1 atau lebih baru untuk target app dan target Widget Extension.
- Uji pada perangkat iOS atau simulator yang kompatibel. Dynamic Island hanya muncul pada model perangkat yang didukung; perangkat lain menggunakan tampilan Lock Screen.
- Pastikan gabungan data statis dan dinamis ActivityKit tetap di bawah batas 4 KB dari Apple.
1. Buat Widget Extension
Bagian berjudul “1. Buat Widget Extension”Buka proyek native iOS:
bunx cap open iosLalu:
- Pilih File > New > Target.
- Tambahkan Widget Extension.
- Aktifkan Sertakan Live Activity.
- Nonaktifkan Sertakan Configuration Intent kecuali jika aplikasi juga membutuhkan widget yang dapat dikonfigurasi.
- Pastikan extension yang dibuat sudah tertanam di target aplikasi utama.
Widget Extension harus berisi ActivityConfiguration dan mendaftarkannya di WidgetBundle. Extension ini harus menyediakan semua tampilan Live Activity yang diperlukan:
- Layar Kunci
- Dynamic Island diperluas
- Dynamic Island compact leading dan trailing
- Dynamic Island minimal
Menambahkan target saja tidak cukup. Aplikasi native atau plugin harus memanggil API request, update, dan end dari ActivityKit. Extension harus berisi SwiftUI code yang dapat men-decode dan merender yang sama ActivityAttributes dan content state yang digunakan oleh panggilan tersebut. Sertakan model ActivityKit yang dibagikan di kedua target aplikasi utama dan Widget Extension. Template Live Activity buatan Xcode tidak secara otomatis merender layout JSON yang dikirim ke plugin ini; extension juga memerlukan renderer layout native yang kompatibel.
2. Aktifkan Live Activities
Bagian berjudul “2. Aktifkan Live Activities”Tambahkan key berikut ke target aplikasi utama Info.plist:
<key>NSSupportsLiveActivities</key><true/>Jika proyek menghasilkan Info.plist, tambahkan Mendukung Live Activities dengan nilai Boolean YES di bagian Custom iOS Target Properties target aplikasi utama sebagai gantinya.
3. Konfigurasi App Group untuk Gambar Bersama
Bagian berjudul “3. Konfigurasi App Group untuk Gambar Bersama”App Group hanya diperlukan saat menggunakan saveImage, removeImage, listImages, atau cleanupImages. Plugin ini mengambil identifier App Group dari bundle identifier aplikasi utama menggunakan format berikut:
group.<MAIN_APP_BUNDLE_ID>.liveactivitiesSebagai contoh, aplikasi dengan bundle identifier com.example.delivery must use:
group.com.example.delivery.liveactivitiesDi Xcode, tambahkan App Groups capability ke target aplikasi utama dan target Widget Extension, lalu aktifkan identifier yang sama pada kedua target tersebut.
Ekstensi Live Activity tidak bisa mengakses jaringan. Download gambar remote di aplikasi utama dan simpan ke shared App Group sebelum digunakan di Live Activity. Untuk gambar yang di-bundle, aktifkan juga Widget Extension pada target membership aset tersebut.
4. Konfigurasi Deep Links
Bagian berjudul “4. Konfigurasi Deep Links”Saat menggunakan behavior.widgetUrl atau rangkaian timer tapUrl, daftarkan URL scheme atau Universal Link yang sesuai di aplikasi utama. Untuk custom scheme seperti myapp://order/12345, tambahkan scheme pada target aplikasi utama di bagian Info > Tipe URL di pengaturan.
5. Opsional: Aktifkan Server-Driven Updates
Bagian berjudul “5. Opsional: Aktifkan Server-Driven Updates”Push Notifications tidak diperlukan untuk update lokal yang dimulai oleh aplikasi. Untuk memulai, memperbarui, atau mengakhiri Live Activities dari server:
- Tambahkan Notifikasi Push capability ke target aplikasi utama.
- Dapatkan token push ActivityKit dan kirim ke server.
- Kirim notifikasi ActivityKit melalui APNs menggunakan
liveactivitytipe push. - Tambah
NSSupportsLiveActivitiesFrequentUpdateske aplikasi utamaInfo.plisthanya jika use case membutuhkan update push yang sering.
Token push ActivityKit terpisah dari token device notifikasi user standar. Mengaktifkan capability Push Notifications saja tidak cukup; update berbasis server memerlukan penanganan token native dan backend APNs.
Checklist Setup Native
Bagian berjudul “Native Setup Checklist”Sebelum memanggil startActivity, pastikan bahwa:
NSSupportsLiveActivitiessudah diaktifkan pada target aplikasi utama.- Widget Extension disematkan dan mendaftarkan
ActivityConfiguration. - Implementasi ActivityKit native dan Widget Extension menggunakan
ActivityAttributestipe. - Target deployment app dan Widget Extension adalah iOS 16.1 atau lebih baru.
- Live Activities diaktifkan untuk app di Pengaturan iOS.
- App Group yang sesuai diaktifkan pada kedua target saat menggunakan gambar bersama.
- Setiap custom URL scheme yang digunakan oleh
widgetUrlatautapUrlterdaftar.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';Mulai cepat
Bagian berjudul “Mulai cepat”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);}Contoh: startActivity
Bagian berjudul “Contoh: 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);Contoh: updateActivity
Bagian berjudul “Contoh: 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!' }});Kesalahan umum
Bagian berjudul “Kesalahan umum”- Listeners: hapus handle saat screen unmount.
- Sinkronisasi Native: jalankan
bunx cap syncsetelah upgrade plugin. - Sumber kebenaran tunggal: percayai
src/definitions.tsdi repo GitHub.
Ringkasan API
Bagian berjudul “Ikhtisar API”areActivitiesSupported
Bagian berjudul “areActivitiesSupported”Periksa apakah Live Activities didukung di perangkat ini. Memerlukan iOS 16.1+ dan dukungan perangkat.
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
Bagian berjudul “startActivity”Mulai Live Activity baru dengan layout dan data yang ditentukan.
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
Bagian berjudul “updateActivity”Update Live Activity yang sudah ada dengan data baru.
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
Bagian berjudul “endActivity”Akhiri 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
Bagian berjudul “getAllActivities”Dapatkan semua Live Activities yang sedang aktif.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { activities } = await CapgoLiveActivities.getAllActivities();activities.forEach(activity => { console.log(`Activity ${activity.activityId}: ${activity.state}`);});saveImage
Bagian berjudul “saveImage”Simpan gambar ke shared App Group container untuk digunakan di Live Activities. Gambar harus disimpan ke shared container agar bisa diakses dari 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 }removeImage
Bagian berjudul “removeImage”Hapus gambar yang tersimpan dari container bersama.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { success } = await CapgoLiveActivities.removeImage({ name: 'product-image' });listImages
Bagian berjudul “listImages”Tampilkan daftar semua gambar yang tersimpan di container bersama.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
const { images } = await CapgoLiveActivities.listImages();console.log('Saved images:', images);cleanupImages
Bagian berjudul “cleanupImages”Hapus semua gambar yang tersimpan dari container bersama.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.cleanupImages();startTimerSequence
Bagian berjudul “startTimerSequence”Mulai urutan timer untuk workout/olahraga. Di iOS: Muncul di Live Activity dan Dynamic Island Di Android: Muncul sebagai notifikasi foreground dengan 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
Bagian berjudul “pauseTimerSequence”Jeda urutan timer.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.pauseTimerSequence({ sequenceId: 'abc123' });resumeTimerSequence
Bagian berjudul “resumeTimerSequence”Lanjutkan urutan timer yang dijeda.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.resumeTimerSequence({ sequenceId: 'abc123' });stopTimerSequence
Bagian berjudul “stopTimerSequence”Hentikan dan tutup urutan timer.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.stopTimerSequence({ sequenceId: 'abc123' });skipTimerStep
Bagian berjudul “skipTimerStep”Lewati ke langkah berikutnya dalam urutan.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.skipTimerStep({ sequenceId: 'abc123' });previousTimerStep
Bagian berjudul “previousTimerStep”Kembali ke langkah sebelumnya dalam urutan.
import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';
await CapgoLiveActivities.previousTimerStep({ sequenceId: 'abc123' });getTimerState
Bagian berjudul “getTimerState”Dapatkan status terkini dari urutan 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`);Referensi Tipe
Bagian berjudul “Referensi Tipe”AreActivitiesSupportedResult
Bagian berjudul “AreActivitiesSupportedResult”Hasil pengecekan apakah activity didukung.
export interface AreActivitiesSupportedResult { /** Whether Live Activities are supported on this device */ supported: boolean; /** Reason if not supported */ reason?: string;}StartActivityOptions
Bagian berjudul “StartActivityOptions”Opsi untuk memulai 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
Bagian berjudul “StartActivityResult”Hasil dari memulai activity.
export interface StartActivityResult { /** Unique activity identifier */ activityId: string;}UpdateActivityOptions
Bagian berjudul “UpdateActivityOptions”Opsi untuk memperbarui 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
Bagian berjudul “EndActivityOptions”Opsi untuk mengakhiri 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
Bagian berjudul “GetAllActivitiesResult”Hasil dari getAllActivities.
export interface GetAllActivitiesResult { /** List of activities */ activities: ActivityInfo[];}SaveImageOptions
Bagian berjudul “SaveImageOptions”Opsi untuk menyimpan gambar.
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
Bagian berjudul “SaveImageResult”Hasil dari menyimpan gambar.
export interface SaveImageResult { /** Whether the save was successful */ success: boolean; /** Saved image name */ imageName: string;}RemoveImageOptions
Bagian berjudul “RemoveImageOptions”Opsi untuk menghapus gambar.
export interface RemoveImageOptions { /** Name of the image to remove */ name: string;}RemoveImageResult
Bagian berjudul “RemoveImageResult”Hasil penghapusan gambar.
export interface RemoveImageResult { /** Whether the removal was successful */ success: boolean;}ListImagesResult
Bagian berjudul “ListImagesResult”Hasil listing gambar.
export interface ListImagesResult { /** List of saved image names */ images: string[];}TimerSequenceOptions
Bagian berjudul “TimerSequenceOptions”Opsi untuk memulai urutan 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;}Sumber Kebenaran
Bagian berjudul “Sumber Kebenaran”Halaman ini dibuat dari plugin src/definitions.ts. Jalankan ulang sync saat API publik berubah di upstream.
Lanjutkan dari Getting Started
Bagian berjudul “Lanjutkan dari Getting Started”Jika Anda menggunakan Panduan Memulai untuk merencanakan operasi dashboard dan API, hubungkan dengan Menggunakan @capgo/capacitor-live-activities untuk kemampuan native di Menggunakan @capgo/capacitor-live-activities, Ringkasan API untuk detail implementasi di API Overview, Pendahuluan untuk detail implementasi di Introduction, Kunci API untuk detail implementasi di API Keys, dan Perangkat untuk detail implementasi di Devices.