Langsung ke konten

Panduan Memulai

GitHub

Anda bisa menggunakan AI-Assisted Setup kami untuk menginstal plugin ini. Tambahkan skill Capgo ke tool AI Anda dengan command berikut:

Jendela terminal
bunx skills add https://github.com/Cap-go/capgo-skills --skill capacitor-plugins

Lalu 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:

Jendela terminal
bun add @capgo/capacitor-live-activities
bunx cap sync

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.

  • 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.

Buka proyek native iOS:

Jendela terminal
bunx cap open ios

Lalu:

  1. Pilih File > New > Target.
  2. Tambahkan Widget Extension.
  3. Aktifkan Sertakan Live Activity.
  4. Nonaktifkan Sertakan Configuration Intent kecuali jika aplikasi juga membutuhkan widget yang dapat dikonfigurasi.
  5. 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.

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>.liveactivities

Sebagai contoh, aplikasi dengan bundle identifier com.example.delivery must use:

group.com.example.delivery.liveactivities

Di 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.

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.

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 liveactivity tipe push.
  • Tambah NSSupportsLiveActivitiesFrequentUpdates ke aplikasi utama Info.plist hanya 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.

Sebelum memanggil startActivity, pastikan bahwa:

  • NSSupportsLiveActivities sudah diaktifkan pada target aplikasi utama.
  • Widget Extension disematkan dan mendaftarkan ActivityConfiguration.
  • Implementasi ActivityKit native dan Widget Extension menggunakan ActivityAttributes tipe.
  • 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 widgetUrl atau tapUrl terdaftar.
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!'
}
});
  • Listeners: hapus handle saat screen unmount.
  • Sinkronisasi Native: jalankan bunx cap sync setelah upgrade plugin.
  • Sumber kebenaran tunggal: percayai src/definitions.ts di repo GitHub.

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

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

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

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

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

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 }

Hapus gambar yang tersimpan dari container bersama.

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

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

Hapus semua gambar yang tersimpan dari container bersama.

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

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

Jeda urutan timer.

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

Lanjutkan urutan timer yang dijeda.

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

Hentikan dan tutup urutan timer.

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

Lewati ke langkah berikutnya dalam urutan.

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

Kembali ke langkah sebelumnya dalam urutan.

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

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

Hasil pengecekan apakah activity didukung.

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

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

Hasil dari memulai activity.

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

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

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

Hasil dari getAllActivities.

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

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

Hasil dari menyimpan gambar.

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

Opsi untuk menghapus gambar.

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

Hasil penghapusan gambar.

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

Hasil listing gambar.

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

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

Halaman ini dibuat dari plugin src/definitions.ts. Jalankan ulang sync saat API publik berubah di upstream.

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.