Memahami persistent mode PHP runtime di NativePHP: menjaga proses PHP tetap hidup, menjalankan background task, scheduling ringan di perangkat, serta perbedaan batasan background execution antara iOS dan Android.

Setelah di episode 10 kita mengelola database SQLite offline dengan Eloquent, pada episode ini kita masuk ke proses background & persistent mode: bagaimana PHP runtime di NativePHP bisa tetap hidup, menjalankan tugas di latar belakang, dan menjadwalkan tugas periodik — sambil memahami batasan platform yang berbeda antara iOS dan Android.
Di aplikasi web, PHP process hidup hanya selama satu request. Di NativePHP, PHP runtime persistent — ia tetap hidup selama aplikasi terbuka, memungkinkan polling, listening events, dan background processing yang berkelanjutan.
Dalam mode normal (web), PHP process berakhir setelah response dikirim. Di NativePHP, PHP runtime berjalan dalam persistent mode: process tidak dimatikan, tetap berjalan di belakang, dan bisa menjalankan tugas kapan saja.
<?php
return [
'persistent' => [
'enabled' => true,
'max_memory_mb' => 256, // batas memori untuk PHP runtime
'idle_timeout_sec' => 300, // timeout jika tidak ada aktivitas
],
];Persistent mode memungkinkan:
Laravel queue bisa berjalan langsung di perangkat menggunakan database driver (SQLite):
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Repositories\NoteRepository;
class SyncNotes implements ShouldQueue
{
use Dispatchable, Queueable;
public function handle(NoteRepository $notes): void
{
$unsynced = $notes->getUnsynced();
foreach ($unsynced as $note) {
try {
\Http::post('https://api.myapp.com/sync/note', [
'id' => $note->id,
'title' => $note->title,
'content' => $note->content,
]);
$note->markSynced();
} catch (\Exception $e) {
// Log error, retry nanti
\Log::error("Sync failed for note {$note->id}: {$e->getMessage()}");
}
}
}
}php artisan queue:work --sleep=30 --tries=3Queue worker ini berjalan di dalam aplikasi — tidak perlu server terpisah. --sleep=30 berarti worker mengecek queue setiap 30 detik, menghemat CPU dan baterai.
Task Scheduler Laravel bisa dijalankan di perangkat untuk tugas periodik:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use App\Jobs\SyncNotes;
use App\Jobs\CleanupOldLogs;
class Kernel
{
protected function schedule(Schedule $schedule): void
{
// Sync notes setiap 15 menit
$schedule->job(new SyncNotes)->everyFifteenMinutes();
// Cleanup log lama setiap malam
$schedule->job(new CleanupOldLogs)->daily();
// Cek update dari server setiap jam
$schedule->call(function () {
$latestVersion = \Http::get('https://api.myapp.com/app/version')
->json('version');
if ($latestVersion !== config('app.version')) {
\Native\Laravel\Facades\Notification::local()
->title('Update Tersedia')
->body('Versi baru tersedia. Perbarui aplikasi.')
->send();
}
})->hourly();
}
}php artisan schedule:workiOS sangat agresif dalam menghentikan aplikasi di background untuk menghemat baterai. NativePHP berjalan dengan batasan:
| Mode | Durasi | Kapan |
|---|---|---|
| Foreground | Tanpa batas | Aplikasi aktif di layar |
| Background fetch | ~30 detik | iOS memberikan waktu terbatas |
| Silent push | ~30 detik | Push notification tanpa suara/alert |
| Background task | ~30 detik | Request dari app saat masuk background |
iOS tidak mengizinkan PHP runtime tetap hidup di background selama berjam-jam. Untuk tugas panjang, gunakan background fetch atau silent push dari server.
Android memberikan lebih banyak fleksibilitas:
| Mode | Durasi | Kapan |
|---|---|---|
| Foreground | Tanpa batas | Aplikasi aktif |
| Foreground service | Tanpa batas | Service dengan notifikasi visible |
| Background service | ~10 menit | Background task biasa |
| WorkManager | Bervariasi | Scheduled task yang dijamin berjalan |
Warning
Android 12+ membatasi background service baru. Gunakan WorkManager atau foreground service untuk task yang membutuhkan waktu lama. Foreground service harus menampilkan notifikasi visible yang memberitahu user bahwa aplikasi sedang bekerja.
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Repositories\NoteRepository;
use Native\Laravel\Facades\Biometric;
class PeriodicSync implements ShouldQueue
{
use Queueable;
public function handle(NoteRepository $notes): void
{
// Hanya sync jika user sudah login (biometric authenticated)
if (!session()->has('biometric_auth')) {
return;
}
$pending = $notes->getPendingCount();
if ($pending > 0) {
$notes->getUnsynced()->each(function ($note) {
\Http::post('https://api.myapp.com/sync', [
'id' => $note->id,
'data' => $note->toArray(),
]);
$note->markSynced();
});
}
}
}Inti yang harus dibawa pulang:
Di episode 12 selanjutnya, kita akan membahas v4 SuperNative: Blade → SwiftUI/Jetpack Compose — revolusi rendering UI tanpa WebView, mapping komponen ke native elements, dan konversi layar WebView-based menjadi native UI murni. Sampai jumpa di episode 12!