Belajar NativePHP - Capstone End-to-End
Episode 25 of 28

Belajar NativePHP - Capstone End-to-End

Membangun aplikasi produksi lengkap dengan NativePHP: task manager dengan login biometrik, data offline SQLite + sync, push notification, UI SuperNative native, CI/CD pipeline, serta dirilis ke TestFlight dan Play internal testing dengan monitoring aktif.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 0-24 kita mempelajari setiap aspek NativePHP secara terpisah — dari setup, arsitektur, device APIs, UI, sync, build, keamanan, performa, hingga monitoring — pada episode ini kita satukan semuanya dalam satu capstone project: aplikasi task manager produksi yang menggunakan seluruh fitur NativePHP.

Capstone ini bukan demo sederhana — ini adalah aplikasi yang bisa kalian publish ke App Store dan Play Store, dengan fitur lengkap yang mencerminkan aplikasi mobile dunia nyata.

Arsitektur Aplikasi

100%

Fitur Utama

  1. Login biometrik (Face ID / Fingerprint)
  2. CRUD task offline-first di SQLite
  3. Sync otomatis ke backend saat online
  4. Push notification untuk reminder
  5. UI SuperNative — SwiftUI/Jetpack Compose asli
  6. CI/CD pipeline ke TestFlight + Play Console
  7. Sentry monitoring aktif

Step 1: Project Setup

Setup project
composer create-project laravel/laravel task-manager
cd task-manager
composer require nativephp/mobile
composer require sentry/sentry-laravel
php artisan native:install

Step 2: Database & Migration

database/migrations/create_tasks_table.php
<?php
 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->enum('priority', ['low', 'medium', 'high'])->default('medium');
            $table->timestamp('due_date')->nullable();
            $table->timestamp('synced_at')->nullable();
            $table->timestamps();
        });
    }
 
    public function down(): void
    {
        Schema::dropIfExists('tasks');
    }
};

Step 3: Login Biometrik

app/Livewire/Auth/BiometricLogin.php
<?php
 
namespace App\Livewire\Auth;
 
use Livewire\Component;
use Native\Laravel\Facades\Biometric;
use Native\Laravel\Facades\SecureStorage;
use Illuminate\Support\Facades\Http;
 
class BiometricLogin extends Component
{
    public $email = '';
    public $password = '';
    public $showBiometricPrompt = false;
 
    public function login()
    {
        $this->validate([
            'email' => 'required|email',
            'password' => 'required|min:6',
        ]);
 
        $response = Http::post(config('app.api_url') . '/auth/login', [
            'email' => $this->email,
            'password' => $this->password,
        ]);
 
        if ($response->successful()) {
            SecureStorage::put('auth_token', $response->json('token'));
            SecureStorage::put('user_email', $this->email);
 
            if (Biometric::isSupported() && Biometric::areBiometricsEnrolled()) {
                $this->showBiometricPrompt = true;
            } else {
                $this->redirectRoute('dashboard');
            }
        }
    }
 
    public function enableBiometric()
    {
        SecureStorage::put('biometric_enabled', 'true');
        $this->redirectRoute('dashboard');
    }
 
    public function loginWithBiometric()
    {
        $result = Biometric::authenticate('Login ke Task Manager');
        if ($result->success) {
            $this->redirectRoute('dashboard');
        }
    }
 
    public function render()
    {
        return view('livewire.auth.biometric-login');
    }
}

Step 4: Task CRUD Offline

app/Services/TaskService.php
<?php
 
namespace App\Services;
 
use App\Models\Task;
use App\Repositories\TaskRepository;
use Illuminate\Support\Facades\Http;
 
class TaskService
{
    public function __construct(
        private TaskRepository $repo
    ) {}
 
    public function create(array $data): Task
    {
        $task = $this->repo->create($data);
        $this->syncToServer($task);
        return $task;
    }
 
    public function toggleComplete(int $id): Task
    {
        $task = $this->repo->toggleComplete($id);
        $this->syncToServer($task);
        return $task;
    }
 
    private function syncToServer(Task $task): void
    {
        try {
            $token = \Native\Laravel\Facades\SecureStorage::get('auth_token');
            Http::withToken($token)
                ->post(config('app.api_url') . '/tasks/sync', [
                    'task' => $task->toArray(),
                ]);
            $task->markSynced();
        } catch (\Exception $e) {
            // Sync gagal, akan dicoba lagi nanti
            $task->markUnsynced();
        }
    }
}

Step 5: Push Notification

Registrasi push notification
<?php
 
use Native\Laravel\Facades\Notification;
 
// Saat login berhasil
$token = Notification::getDeviceToken();
 
Http::withToken($authToken)
    ->post(config('app.api_url') . '/devices/register', [
        'token' => $token,
        'platform' => PHP_OS_FAMILY === 'Darwin' ? 'ios' : 'android',
    ]);

Step 6: CI/CD Pipeline

.github/workflows/release.yml
name: Release
 
on:
  push:
    tags:
      - 'v*'
 
jobs:
  build-ios:
    runs-on: macos-14
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with: { php-version: '8.3' }
      - run: composer install --no-dev --optimize-autoloader
      - run: npm ci && npm run build
      - run: php artisan native:build ios --release
      - run: |
          xcrun altool --upload-app \
            --type ios \
            --file build/Export/NativePHPApp.ipa
 
  build-android:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with: { php-version: '8.3' }
      - uses: actions/setup-java@v4
        with: { java-version: '17', distribution: 'temurin' }
      - run: composer install --no-dev --optimize-autoloader
      - run: npm ci && npm run build
      - run: php artisan native:build android --release

Step 7: Monitoring

Sentry initialization
<?php
 
// config/sentry.php
return [
    'dsn' => env('SENTRY_DSN'),
    'traces_sample_rate' => 1.0,
    'release' => env('APP_VERSION'),
];

Penutup

Capstone ini membuktikan bahwa satu developer PHP bisa membangun aplikasi mobile native yang berfungsi penuh — dari login biometrik hingga CI/CD ke kedua store. Seluruh fitur NativePHP terintegrasi dalam satu aplikasi produksi yang realistis.

Di episode 26 selanjutnya, kita akan membahas Ekosistem & Tren Modern 2026 — momentum NativePHP, platform support, posisi di ekosistem mobile, dan tren "bahasa familiar untuk native" yang sedang berkembang. Sampai jumpa di episode 26!

Belajar NativePHP - Capstone End-to-End | Belajar NativePHP