pulse_monitoring 0.1.2
pulse_monitoring: ^0.1.2 copied to clipboard
Flutter plugin for Pulse Monitoring, sessions, errors, HTTP metrics and in-app information.
Pulse Monitoring for Flutter #
Plugin Flutter untuk monitoring sesi, crash, error, HTTP, screen, event, dan informasi in-app dari dashboard Pulse. Versi plugin 0.1.2 menggunakan SDK native Android dan iOS 0.1.1.
Pemilik: Idris — idris3097@gmail.com.
Platform yang didukung #
| Platform | Dukungan | Persyaratan dan batasan |
|---|---|---|
| Android | Ya | Android 8.0 / API 26+, compileSdk 37+, Java 17. Perangkat dan emulator. |
| iOS | Ya | iOS 15+, instalasi melalui CocoaPods. Perangkat arm64; simulator arm64 dan x86_64. |
| Web | Belum | Tidak ada implementasi monitoring web. |
| macOS, Windows, Linux | Belum | Tidak ada implementasi monitoring desktop. |
Persyaratan Flutter: Flutter 3.41+ dan Dart >=3.11.0 <4.0.0.
Pada platform yang belum didukung, start() tidak mengaktifkan monitoring.
Untuk compileSdk 37, gunakan Android Gradle Plugin 9.1.1+ dan Gradle yang kompatibel dengan versi AGP aplikasi. Lihat tabel kompatibilitas Android. Untuk iOS, gunakan Xcode yang kompatibel dengan Flutter dan binary Swift yang disertakan. Build simulator telah diverifikasi dengan Xcode 27.1. Plugin Flutter ini belum mendukung instalasi melalui Swift Package Manager; gunakan integrasi CocoaPods pada aplikasi Flutter.
Fitur dan cara pengumpulan #
| Fitur | Cara penggunaan |
|---|---|
| Sesi dan metadata perangkat/aplikasi | Otomatis setelah start(). |
| Crash Android | Uncaught JVM exceptions; crash NDK/sinyal belum ditangkap. |
| Crash iOS | Diagnostics MetricKit; pengiriman mengikuti jadwal sistem Apple. |
| Error Flutter/Dart | Teruskan melalui recordError() atau handler error aplikasi. |
| Metrik HTTP Dart | Panggil recordHttp() dari HTTP client aplikasi. Tidak ada interceptor Dart otomatis. |
| Screen | Pasang PulseNavigatorObserver pada Navigator, atau panggil trackScreen() secara manual. |
| Event bisnis | Panggil trackEvent(). |
| Maintenance | Dengarkan maintenance dan tampilkan chip; detail dibuka dengan showMaintenance(). |
| Informasi new feature/banner | Feed dan presentasi informasi ditangani SDK native. |
| Push informasi | Opsional; teruskan data FCM melalui handlePush(). Firebase dikonfigurasi aplikasi. |
Force update: plugin belum menyediakan pengecekan versi aplikasi atau bottom sheet force update. Aplikasi perlu memanggil API versi miliknya dan menampilkan UI update. Maintenance dan force update adalah dua alur yang terpisah.
1. Instalasi #
Tambahkan dependency dari pub.dev:
dependencies:
pulse_monitoring: ^0.1.2
flutter pub get
Untuk iOS:
cd ios
pod install
cd ..
Flutter mendaftarkan plugin secara otomatis. Tidak perlu menambahkan SDK manual
ke Gradle aplikasi, Podfile, MainActivity, atau AppDelegate. Folder
ios/.symlinks/plugins/pulse_monitoring dikelola Flutter; jangan diedit atau
dimasukkan ke Git.
Android mengambil dependency native dari Maven Central. Package Flutter membawa XCFramework iOS, sehingga pemasangan tidak memerlukan akses repository GitHub.
2. Inisialisasi #
Ambil workspace key dari dashboard Pulse → Pengaturan → Workspace. Pastikan aplikasi terdaftar dengan package/bundle ID dan platform yang sesuai.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:pulse_monitoring/pulse_monitoring.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// Jika menggunakan Firebase, inisialisasikan Firebase terlebih dahulu.
await PulseMonitoring.start(
workspaceKey: const String.fromEnvironment('PULSE_WORKSPACE_KEY'),
debug: kDebugMode,
autoMaintenancePopups: false,
);
runApp(MaterialApp(
navigatorObservers: [PulseNavigatorObserver()],
home: const Scaffold(body: Center(child: Text('Home'))),
));
}
flutter run --dart-define=PULSE_WORKSPACE_KEY=pk_workspace_anda
Panggil start() sekali di main isolate, setelah Flutter binding siap dan sebelum
mengirim event atau identitas user. Key kosong menonaktifkan inisialisasi; pastikan
konfigurasi build production menyediakan key. Pelaporan sebelum SDK aktif diabaikan.
await start() menunggu inisialisasi bridge, bukan konfirmasi data diterima server.
Opsi start() |
Default | Kegunaan |
|---|---|---|
workspaceKey |
Wajib | Public workspace key dari dashboard. |
baseUrl |
https://pulse-api-mobile.vercel.app/api/v1 |
Endpoint API lengkap, termasuk /api/v1, untuk server sendiri. |
debug |
false |
Log diagnostik SDK; aktifkan saat pengembangan atau troubleshooting. |
autoMaintenancePopups |
false |
Aktifkan hanya jika ingin dialog maintenance otomatis. |
Untuk dev dan production, gunakan workspace key serta endpoint yang sesuai dengan
lingkungan masing-masing. --dart-define bukan penyimpanan secret; jangan masukkan
credential admin, private key, atau token server ke aplikasi.
3. Identitas user dan event #
Sesudah login berhasil, gunakan ID internal yang stabil. Bersihkan identitas ketika logout agar event selanjutnya tidak terkait akun sebelumnya.
PulseMonitoring.setUser('user_123');
PulseMonitoring.trackEvent('document_sent', {
'document_count': 2,
'delivery_method': 'email',
'success': true,
});
// Saat logout:
PulseMonitoring.setUser(null);
Gunakan nama event yang konsisten dan properties sederhana: string, angka, atau boolean. Hindari email, nama lengkap, isi dokumen, token, dan data sensitif lain.
Untuk screen, PulseNavigatorObserver membaca RouteSettings.name pada
PageRoute. Pasang observer pada Navigator yang digunakan router aplikasi dan
beri nama route. Jika router tidak memberikan nama, laporkan screen secara manual:
PulseMonitoring.trackScreen('document_detail');
Gunakan satu mekanisme pelaporan untuk screen yang sama agar tidak duplikat.
4. Error Flutter dan error yang ditangani aplikasi #
Plugin tidak memasang handler error Flutter secara otomatis. Untuk error yang sudah ditangani, laporkan setelah aplikasi menentukan cara pemulihannya:
try {
// Operasi aplikasi.
} catch (error, stack) {
PulseMonitoring.recordError(error, stack);
// Tampilkan pesan atau lakukan pemulihan sesuai alur aplikasi.
}
Untuk menghubungkan error global, pasang handler sekali setelah start().
Pertahankan handler yang sudah dipasang aplikasi atau Crashlytics:
import 'dart:ui' show PlatformDispatcher;
import 'package:flutter/foundation.dart' show FlutterError;
import 'package:pulse_monitoring/pulse_monitoring.dart';
void installPulseErrorHandlers() {
final previousFlutterError = FlutterError.onError;
FlutterError.onError = (details) {
PulseMonitoring.recordError(details.exception, details.stack);
if (previousFlutterError != null) {
previousFlutterError(details);
} else {
FlutterError.presentError(details);
}
};
final previousPlatformError = PlatformDispatcher.instance.onError;
PlatformDispatcher.instance.onError = (error, stack) {
PulseMonitoring.recordError(error, stack, fatal: true);
return previousPlatformError?.call(error, stack) ?? false;
};
}
Sesuaikan fatal dengan kebijakan error aplikasi. Jangan melaporkan exception
yang sama berulang melalui catch, zone, dan handler global. Error dari isolate
lain perlu diteruskan melalui mekanisme error isolate milik aplikasi.
Lihat penanganan error Flutter.
5. Metrik HTTP #
Tambahkan recordHttp() pada HTTP client/interceptor yang sudah dipakai aplikasi.
Contoh berikut memakai package:http; tambahkan dependency http jika diperlukan.
import 'package:http/http.dart' as http;
import 'package:pulse_monitoring/pulse_monitoring.dart';
Future<http.Response> monitoredGet(http.Client client, Uri uri) async {
final watch = Stopwatch()..start();
try {
final response = await client.get(uri).timeout(const Duration(seconds: 15));
PulseMonitoring.recordHttp(
method: 'GET',
url: uri,
status: response.statusCode,
duration: watch.elapsed,
responseBytes: response.bodyBytes.length,
);
return response;
} catch (error) {
PulseMonitoring.recordHttp(
method: 'GET',
url: uri,
status: 0,
duration: watch.elapsed,
error: error.runtimeType.toString(),
);
rethrow;
} finally {
watch.stop();
}
}
SDK membuang credentials URL, query string, dan fragment sebelum mengirim metrik
melalui bridge. Path URL serta string error tetap perlu diperiksa oleh aplikasi;
jangan memasukkan ID sensitif atau isi respons ke dalamnya. API recordHttp()
tidak menerima request/response body atau header. Jangan membuat request monitoring
kedua jika client aplikasi sudah melaporkan request yang sama.
Gunakan kembali HTTP client milik aplikasi dan tutup client ketika service atau
pemiliknya di-dispose, sehingga koneksi dapat dipakai kembali antar-request.
6. Maintenance chip #
PulseMonitoring.maintenance menyediakan ValueNotifier<PulseMaintenance?>.
Nilainya null ketika tidak ada maintenance aktif. Biarkan SDK mengelola notifier
ini pada aplikasi production.
ValueListenableBuilder<PulseMaintenance?>(
valueListenable: PulseMonitoring.maintenance,
builder: (context, maintenance, child) {
if (maintenance == null) return const SizedBox.shrink();
return ActionChip(
avatar: Icon(Icons.info_outline, color: maintenance.color),
label: Text(maintenance.title),
onPressed: PulseMonitoring.showMaintenance,
);
},
)
Import package:flutter/material.dart untuk widget di atas. Pertahankan
autoMaintenancePopups: false jika memakai chip, sehingga maintenance tidak
membuka dialog otomatis. Menekan chip membuka detail maintenance melalui SDK native.
Untuk dialog otomatis, set autoMaintenancePopups: true saat inisialisasi.
7. Push informasi dengan Firebase (opsional) #
Monitoring dasar tidak memerlukan Firebase. Untuk push, aplikasi perlu memasang
serta mengonfigurasi firebase_core dan firebase_messaging, permission notifikasi,
dan konfigurasi APNs/FCM sesuai platform. Setelah Firebase dan Pulse siap,
teruskan pesan saat foreground dan saat notifikasi dibuka:
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:pulse_monitoring/pulse_monitoring.dart';
void routeMessage(RemoteMessage message) {
if (PulseMonitoring.handlePush(message.data)) return;
// Lanjutkan handler pesan aplikasi yang lain di sini.
}
Future<void> configurePulsePush() async {
FirebaseMessaging.onMessage.listen(routeMessage);
FirebaseMessaging.onMessageOpenedApp.listen(routeMessage);
final initial = await FirebaseMessaging.instance.getInitialMessage();
if (initial != null) routeMessage(initial);
}
handlePush() mengenali data type: information dan meminta SDK memperbarui feed
informasi. Nilai true berarti pesan telah diteruskan, bukan konfirmasi popup sudah
terlihat. Aturan maintenance tetap mengikuti autoMaintenancePopups.
Daftarkan listener sekali dan batalkan subscription ketika pemiliknya di-dispose.
Plugin ini digunakan dari main isolate; jangan memanggilnya langsung dari
background isolate FCM. Untuk konfigurasi lengkap, ikuti
panduan penerimaan pesan Firebase.
Praktik integrasi yang disarankan #
- Mulai SDK sebelum mengirim event, lalu set user setelah session login tersedia.
- Gunakan ID internal dan properties yang tidak memuat data sensitif.
- Pertahankan handler error dan alur push aplikasi yang sudah ada; hindari laporan duplikat.
- Gunakan observer route atau pelaporan screen manual sesuai router aplikasi.
- Biarkan antrean dan retry SDK berjalan; jangan memanggil
flush()pada setiap event. - Gunakan
PulseMonitoring.flush()untuk meminta upload segera saat diperlukan. Pemanggilan ini tidak menunggu upload selesai atau menjamin server menerima data. - Validasi pengiriman melalui dashboard pada perangkat uji. Antrean offline memiliki batas kapasitas; SDK tidak menjamin pengiriman setiap event.
- Uji Android release dengan minification aktif serta iOS pada perangkat fisik. Simulator saja tidak membuktikan penerimaan diagnostics MetricKit.
SDK menyertakan PrivacyInfo.xcprivacy pada framework iOS. Deklarasi privasi aplikasi
perlu mencerminkan identitas user, event custom, dan data lain yang benar-benar dikirim.
Diagnostics crash iOS mengikuti jadwal Apple dan tidak dijamin muncul saat launch
berikutnya. Android belum menangkap crash NDK/sinyal. Gunakan crash reporter lain
sesuai kebutuhan aplikasi.
Upgrade dan troubleshooting #
Untuk memperbarui package yang sudah terpasang:
flutter pub upgrade pulse_monitoring
cd ios
pod update pulse_monitoring --no-repo-update
cd ..
| Masalah | Pemeriksaan |
|---|---|
checkReleaseAarMetadata menyebut android-36 |
Gunakan plugin 0.1.2+ dan compileSdk aplikasi 37+. Periksa versi yang terpilih pada pubspec.lock. |
| SDK tidak mengirim data | Pastikan workspace key terisi, endpoint dapat diakses, serta package/bundle ID terdaftar pada workspace yang benar. |
| Maintenance chip tidak muncul | Pastikan konten published, jadwal aktif, target platform/package cocok, dan feed sudah diterima. Periksa juga ID flavor dev/prod. |
| Screen tidak tercatat | Beri nama route atau panggil trackScreen() manual. |
| Error/HTTP Dart tidak tercatat | Hubungkan handler error dan HTTP client seperti contoh di atas. |
Error MissingPluginException setelah menambah dependency |
Hentikan aplikasi, jalankan pub get/Pods, lalu build ulang penuh; hot reload tidak mendaftarkan plugin native baru. |
| Push tidak muncul | Periksa Firebase/APNs, permission, data type: information, serta forwarding pesan pada main isolate. |
| Crash iOS belum masuk dashboard | Periksa diagnostics pada perangkat; pengiriman MetricKit dapat tertunda. |
Versi native, contoh, dan lisensi #
- Plugin Flutter: 0.1.2.
- Android native:
io.github.mhmadidris:pulse-monitoring:0.1.1dari Maven Central. - iOS native: XCFramework 0.1.1, termasuk privacy manifest dan Swift interfaces.
- Contoh pemakaian: example/lib/main.dart.
Versi plugin dapat naik sendiri untuk perbaikan integrasi tanpa mengganti SDK native. Source implementasi Swift SDK, dSYM, dan archive Xcode tidak disertakan dalam package Flutter. Bridge Flutter dan binary iOS ikut tersedia pada pub.dev; repository GitHub dapat tetap private.
Penggunaan plugin dan binary iOS tunduk pada LICENSE. SDK Android native yang didistribusikan terpisah menggunakan Apache License 2.0. Hubungi idris3097@gmail.com untuk izin penggunaan atau pertanyaan integrasi.