From 9192d5108d8e7e9dbf4bc9886fdfe01ab3ae85df Mon Sep 17 00:00:00 2001 From: Shane Rosenthal Date: Fri, 7 Nov 2025 17:16:20 -0500 Subject: [PATCH] Add mobile 2.x documentation and version switcher Introduces comprehensive documentation for the mobile 2.x platform, including API references (biometrics, browser, camera, device, dialog, geolocation, haptics, push notifications, QR code, secure storage, system), concepts (CI/CD, databases, deep links, push notifications, security), and EDGE components (bottom nav, FAB, side nav, top bar). Also updates the docs index view to support a version switcher for the mobile platform. --- resources/views/docs/index.blade.php | 10 + resources/views/docs/mobile/2/_index.md | 4 + resources/views/docs/mobile/2/apis/_index.md | 4 + .../views/docs/mobile/2/apis/biometrics.md | 61 ++++++ resources/views/docs/mobile/2/apis/browser.md | 58 +++++ resources/views/docs/mobile/2/apis/camera.md | 90 ++++++++ resources/views/docs/mobile/2/apis/device.md | 55 +++++ resources/views/docs/mobile/2/apis/dialog.md | 103 +++++++++ .../views/docs/mobile/2/apis/geolocation.md | 155 ++++++++++++++ resources/views/docs/mobile/2/apis/haptics.md | 29 +++ .../docs/mobile/2/apis/push-notifications.md | 63 ++++++ resources/views/docs/mobile/2/apis/qrcode.md | 91 ++++++++ .../docs/mobile/2/apis/secure-storage.md | 87 ++++++++ resources/views/docs/mobile/2/apis/system.md | 36 ++++ .../views/docs/mobile/2/concepts/_index.md | 4 + .../views/docs/mobile/2/concepts/ci-cd.md | 159 ++++++++++++++ .../views/docs/mobile/2/concepts/databases.md | 149 +++++++++++++ .../docs/mobile/2/concepts/deep-links.md | 92 ++++++++ .../mobile/2/concepts/push-notifications.md | 93 ++++++++ .../views/docs/mobile/2/concepts/security.md | 104 +++++++++ .../docs/mobile/2/edge-components/_index.md | 4 + .../mobile/2/edge-components/bottom-nav.md | 46 ++++ .../docs/mobile/2/edge-components/fab.md | 42 ++++ .../docs/mobile/2/edge-components/side-nav.md | 97 +++++++++ .../docs/mobile/2/edge-components/top-bar.md | 42 ++++ .../docs/mobile/2/getting-started/_index.md | 4 + .../mobile/2/getting-started/configuration.md | 139 ++++++++++++ .../mobile/2/getting-started/development.md | 201 ++++++++++++++++++ .../2/getting-started/environment-setup.md | 144 +++++++++++++ .../mobile/2/getting-started/installation.md | 159 ++++++++++++++ .../mobile/2/getting-started/introduction.md | 74 +++++++ .../mobile/2/getting-started/quick-start.md | 56 +++++ .../docs/mobile/2/getting-started/roadmap.md | 45 ++++ .../2/getting-started/support-policy.md | 22 ++ .../mobile/2/getting-started/versioning.md | 69 ++++++ .../views/docs/mobile/2/the-basics/_index.md | 4 + .../docs/mobile/2/the-basics/app-icon.md | 25 +++ .../views/docs/mobile/2/the-basics/assets.md | 28 +++ .../views/docs/mobile/2/the-basics/edge.md | 44 ++++ .../views/docs/mobile/2/the-basics/events.md | 112 ++++++++++ .../mobile/2/the-basics/native-functions.md | 33 +++ .../docs/mobile/2/the-basics/overview.md | 58 +++++ .../mobile/2/the-basics/splash-screens.md | 18 ++ .../docs/mobile/2/the-basics/web-view.md | 132 ++++++++++++ 44 files changed, 3045 insertions(+) create mode 100644 resources/views/docs/mobile/2/_index.md create mode 100644 resources/views/docs/mobile/2/apis/_index.md create mode 100644 resources/views/docs/mobile/2/apis/biometrics.md create mode 100644 resources/views/docs/mobile/2/apis/browser.md create mode 100644 resources/views/docs/mobile/2/apis/camera.md create mode 100644 resources/views/docs/mobile/2/apis/device.md create mode 100644 resources/views/docs/mobile/2/apis/dialog.md create mode 100644 resources/views/docs/mobile/2/apis/geolocation.md create mode 100644 resources/views/docs/mobile/2/apis/haptics.md create mode 100644 resources/views/docs/mobile/2/apis/push-notifications.md create mode 100644 resources/views/docs/mobile/2/apis/qrcode.md create mode 100644 resources/views/docs/mobile/2/apis/secure-storage.md create mode 100644 resources/views/docs/mobile/2/apis/system.md create mode 100644 resources/views/docs/mobile/2/concepts/_index.md create mode 100644 resources/views/docs/mobile/2/concepts/ci-cd.md create mode 100644 resources/views/docs/mobile/2/concepts/databases.md create mode 100644 resources/views/docs/mobile/2/concepts/deep-links.md create mode 100644 resources/views/docs/mobile/2/concepts/push-notifications.md create mode 100644 resources/views/docs/mobile/2/concepts/security.md create mode 100644 resources/views/docs/mobile/2/edge-components/_index.md create mode 100644 resources/views/docs/mobile/2/edge-components/bottom-nav.md create mode 100644 resources/views/docs/mobile/2/edge-components/fab.md create mode 100644 resources/views/docs/mobile/2/edge-components/side-nav.md create mode 100644 resources/views/docs/mobile/2/edge-components/top-bar.md create mode 100644 resources/views/docs/mobile/2/getting-started/_index.md create mode 100644 resources/views/docs/mobile/2/getting-started/configuration.md create mode 100644 resources/views/docs/mobile/2/getting-started/development.md create mode 100644 resources/views/docs/mobile/2/getting-started/environment-setup.md create mode 100644 resources/views/docs/mobile/2/getting-started/installation.md create mode 100644 resources/views/docs/mobile/2/getting-started/introduction.md create mode 100644 resources/views/docs/mobile/2/getting-started/quick-start.md create mode 100644 resources/views/docs/mobile/2/getting-started/roadmap.md create mode 100644 resources/views/docs/mobile/2/getting-started/support-policy.md create mode 100644 resources/views/docs/mobile/2/getting-started/versioning.md create mode 100644 resources/views/docs/mobile/2/the-basics/_index.md create mode 100644 resources/views/docs/mobile/2/the-basics/app-icon.md create mode 100644 resources/views/docs/mobile/2/the-basics/assets.md create mode 100644 resources/views/docs/mobile/2/the-basics/edge.md create mode 100644 resources/views/docs/mobile/2/the-basics/events.md create mode 100644 resources/views/docs/mobile/2/the-basics/native-functions.md create mode 100644 resources/views/docs/mobile/2/the-basics/overview.md create mode 100644 resources/views/docs/mobile/2/the-basics/splash-screens.md create mode 100644 resources/views/docs/mobile/2/the-basics/web-view.md diff --git a/resources/views/docs/index.blade.php b/resources/views/docs/index.blade.php index f15e8282..61654934 100644 --- a/resources/views/docs/index.blade.php +++ b/resources/views/docs/index.blade.php @@ -10,6 +10,11 @@ 1 => '1.x', 2 => '2.x' ]" /> + @elseif($platform === 'mobile') + @endif @@ -30,6 +35,11 @@ 1 => '1.x', 2 => '2.x' ]" /> + @elseif($platform === 'mobile') + @endif {{-- Copy as Markdown Button --}} diff --git a/resources/views/docs/mobile/2/_index.md b/resources/views/docs/mobile/2/_index.md new file mode 100644 index 00000000..c719fbe2 --- /dev/null +++ b/resources/views/docs/mobile/2/_index.md @@ -0,0 +1,4 @@ +--- +title: Mobile +order: 1 +--- diff --git a/resources/views/docs/mobile/2/apis/_index.md b/resources/views/docs/mobile/2/apis/_index.md new file mode 100644 index 00000000..31293365 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/_index.md @@ -0,0 +1,4 @@ +--- +title: APIs +order: 4 +--- diff --git a/resources/views/docs/mobile/2/apis/biometrics.md b/resources/views/docs/mobile/2/apis/biometrics.md new file mode 100644 index 00000000..da6ec6b4 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/biometrics.md @@ -0,0 +1,61 @@ +--- +title: Biometrics +order: 100 +--- + +## Overview + +The Biometrics API allows you to authenticate users using their device's biometric sensors like Face ID, Touch ID, or +fingerprint scanners. + +```php +use Native\Mobile\Facades\Biometrics; +``` + +## Methods + +### `prompt()` + +Prompts the user for biometric authentication. + +```php +use Native\Mobile\Facades\Biometrics; + +Biometrics::prompt(); +``` + +## Events + +### `Completed` + +Fired when biometric authentication completes (success or failure). + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Biometric\Completed; + +#[On('native:'.Completed::class)] +public function handle(Completed $event) +{ + if ($event->success) { + // User authenticated successfully + $this->unlockSecureFeature(); + } else { + // Authentication failed + $this->showErrorMessage(); + } +} +``` + +## Platform Support + +- **iOS:** Face ID, Touch ID +- **Android:** Fingerprint, Face unlock, other biometric methods +- **Fallback:** System authentication (PIN, password, pattern) + +## Security Notes + +- Biometric authentication provides **convenience**, not absolute security +- Always combine with other authentication factors for sensitive operations +- Consider implementing session timeouts for unlocked states +- Users can potentially bypass biometrics if their device is compromised diff --git a/resources/views/docs/mobile/2/apis/browser.md b/resources/views/docs/mobile/2/apis/browser.md new file mode 100644 index 00000000..8baea45e --- /dev/null +++ b/resources/views/docs/mobile/2/apis/browser.md @@ -0,0 +1,58 @@ +--- +title: Browser +order: 150 +--- + +## Overview + +The Browser API provides three methods for opening URLs, each designed for specific use cases: +in-app browsing, system browser navigation, and web authentication flows. + +```php +use Native\Mobile\Facades\Browser; +``` + +## Methods + +### `inApp()` + +Opens a URL in an embedded browser within your app using Custom Tabs (Android) or SFSafariViewController (iOS). + +```php +Browser::inApp('https://nativephp.com/mobile'); +``` + +### `open()` + +Opens a URL in the device's default browser app, leaving your application entirely. + +```php +Browser::open('https://nativephp.com/mobile'); +``` + +### `auth()` + +Opens a URL in a specialized authentication browser designed for OAuth flows with automatic `nativephp://` redirect handling. + +```php +Browser::auth('https://provider.com/oauth/authorize?client_id=123&redirect_uri=nativephp://127.0.0.1/auth/callback'); +``` + +## Use Cases + +### When to Use Each Method + +**`inApp()`** - Keep users within your app experience: +- Documentation, help pages, terms of service +- External content that relates to your app +- When you want users to easily return to your app + +**`open()`** - Full browser experience needed: +- Complex web applications +- Content requiring specific browser features +- When users need bookmarking or sharing capabilities + +**`auth()`** - OAuth authentication flows: +- Login with WorkOS, Auth0, Google, Facebook, etc. +- Secure authentication with automatic redirects +- Isolated browser session for security diff --git a/resources/views/docs/mobile/2/apis/camera.md b/resources/views/docs/mobile/2/apis/camera.md new file mode 100644 index 00000000..24841f0d --- /dev/null +++ b/resources/views/docs/mobile/2/apis/camera.md @@ -0,0 +1,90 @@ +--- +title: Camera +order: 200 +--- + +## Overview + +The Camera API provides access to the device's camera for taking photos and selecting images from the gallery. + +```php +use Native\Mobile\Facades\Camera; +``` + +## Methods + +### `getPhoto()` + +Opens the camera interface to take a photo. + +```php +Camera::getPhoto(); +``` + +### `pickImages()` + +Opens the gallery/photo picker to select existing images. + +**Parameters:** +- `string $media_type` - Type of media to pick: `'all'`, `'images'`, `'videos'` (default: `'all'`) +- `bool $multiple` - Allow multiple selection (default: `false`) + +**Returns:** `bool` - `true` if picker opened successfully + +```php +// Pick a single image +Camera::pickImages('images', false); + +// Pick multiple images +Camera::pickImages('images', true); + +// Pick any media type +Camera::pickImages('all', true); +``` + +## Events + +### `PhotoTaken` + +Fired when a photo is taken with the camera. + +**Payload:** `string $path` - File path to the captured photo + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Camera\PhotoTaken; + +#[On('native:'.PhotoTaken::class)] +public function handlePhotoTaken(string $path) +{ + // Process the captured photo + $this->processPhoto($path); +} +``` + +### `MediaSelected` + +Fired when media is selected from the gallery. + +**Payload:** `array $media` - Array of selected media items + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Gallery\MediaSelected; + +#[On('native:'.MediaSelected::class)] +public function handleMediaSelected($success, $files, $count) +{ + foreach ($files as $file) { + // Process each selected media item + $this->processMedia($file); + } +} +``` + +## Notes + +- The first time your app requests camera access, users will be prompted for permission +- If permission is denied, camera functions will fail silently +- Captured photos are stored in the app's temporary directory +- File formats are platform-dependent (typically JPEG) diff --git a/resources/views/docs/mobile/2/apis/device.md b/resources/views/docs/mobile/2/apis/device.md new file mode 100644 index 00000000..22698933 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/device.md @@ -0,0 +1,55 @@ +--- +title: Device +order: 200 +--- + +## Overview + +The Device API exposes internal information about the device, such as the model and operating system version, along with user information such as unique ids. +```php +use Native\Mobile\Facades\Device; +``` + +## Methods + +### `getId()` + +Return a unique identifier for the device. + +Returns: `string` + +### `getInfo()` + +Return information about the underlying device/os/platform. + +Returns JSON encoded: `string` + + +### `getBatteryInfo()` + +Return information about the battery. + +Returns JSON encoded: `string` + +## Device Info + +| Prop | Type | Description +|---|---|---|---| +| name | string | The name of the device. For example, "John's iPhone". On iOS 16+ this will return a generic device name without the appropriate entitlements. +| model | string | The device model. For example, "iPhone13,4". +| platform | 'ios' \| 'android' | The device platform (lowercase). +| operatingSystem | string | The operating system of the device. +| osVersion | string | The version of the device OS. +| iOSVersion | number | The iOS version number. Only available on iOS. Multi-part version numbers are crushed down into an integer padded to two-digits, e.g., "16.3.1" β†’ `160301`. | 5.0.0 | +| androidSDKVersion | number | The Android SDK version number. Only available on Android. | 5.0.0 | +| manufacturer | string | The manufacturer of the device. +| isVirtual | boolean | Whether the app is running in a simulator/emulator. +| memUsed | number | Approximate memory used by the current app, in bytes. Divide by 1,048,576 to get MBs used. +| webViewVersion | string | The web view browser version. + +## Battery Info + +| Prop | Type | Description +|---|---|---|---| +| batteryLevel | number | A percentage (0 to 1) indicating how much the battery is charged. +| isCharging | boolean | Whether the device is charging. diff --git a/resources/views/docs/mobile/2/apis/dialog.md b/resources/views/docs/mobile/2/apis/dialog.md new file mode 100644 index 00000000..ad7bc558 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/dialog.md @@ -0,0 +1,103 @@ +--- +title: Dialog +order: 300 +--- + +## Overview + +The Dialog API provides access to native UI elements like alerts, toasts, and sharing interfaces. + +```php +use Native\Mobile\Facades\Dialog; +``` + +## Methods + +### `alert()` + +Displays a native alert dialog with customizable buttons. + +**Parameters:** +- `string $title` - The alert title +- `string $message` - The alert message +- `array $buttons` - Array of button labels (max 3 buttons) + +**Button Positioning:** +- **1 button** - Positive (OK/Confirm) +- **2 buttons** - Negative (Cancel) + Positive (OK/Confirm) +- **3 buttons** - Negative (Cancel) + Neutral (Maybe) + Positive (OK/Confirm) + +```php +Dialog::alert( + 'Confirm Action', + 'Are you sure you want to delete this item?', + ['Cancel', 'Delete'] +); +``` + +### `toast()` + +Displays a brief toast notification message. + + +**Parameters:** +- `string $message` - The message to display + +```php +Dialog::toast('Item saved successfully!'); +``` + +#### Good toast messages + +- Short and clear +- Great for confirmations and status updates +- Don't rely on them for critical information +- Avoid showing multiple toasts in quick succession + +### `share()` + +Opens the native sharing interface. + +**Parameters:** +- `string $title` - The share dialog title +- `string $text` - Text content to share +- `string $url` - URL to share + +```php +Dialog::share( + 'Check this out!', + 'I found this amazing Laravel package for mobile development', + 'https://nativephp.com' +); +``` + +## Events + +### `ButtonPressed` + +Fired when a button is pressed in an alert dialog. + +**Payload:** +- `int $index` - Index of the pressed button (0-based) +- `string $label` - Label/text of the pressed button + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Alert\ButtonPressed; + +#[On('native:'.ButtonPressed::class)] +public function handleAlertButton($index, $label) +{ + switch ($index) { + case 0: + // First button (usually Cancel) + Dialog::toast("You pressed '{$label}'"); + break; + case 1: + // Second button (usually OK/Confirm) + $this->performAction(); + Dialog::toast("You pressed '{$label}'"); + break; + } +} +``` diff --git a/resources/views/docs/mobile/2/apis/geolocation.md b/resources/views/docs/mobile/2/apis/geolocation.md new file mode 100644 index 00000000..0a2e4f84 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/geolocation.md @@ -0,0 +1,155 @@ +--- +title: Geolocation +order: 400 +--- + +## Overview + +The Geolocation API provides access to the device's GPS and location services to determine the user's current position. + +```php +use Native\Mobile\Facades\Geolocation; +``` + +## Methods + +### `getCurrentPosition()` + +Gets the current GPS location of the device. + +**Parameters:** +- `bool $fineAccuracy` - Whether to use high accuracy mode (GPS vs network) (default: `false`) + +**Returns:** Location data via events + +```php +// Get location using network positioning (faster, less accurate) +Geolocation::getCurrentPosition(); + +// Get location using GPS (slower, more accurate) +Geolocation::getCurrentPosition(true); +``` + +### `checkPermissions()` + +Checks the current location permissions status. + +**Returns:** Permission status via events + +```php +Geolocation::checkPermissions(); +``` + +### `requestPermissions()` + +Requests location permissions from the user. + +**Returns:** Permission status after request via events + +```php +Geolocation::requestPermissions(); +``` + +## Events + +### `LocationReceived` + +Fired when location data is requested (success or failure). + +**Event Parameters:** +- `bool $success` - Whether location was successfully retrieved +- `float $latitude` - Latitude coordinate (when successful) +- `float $longitude` - Longitude coordinate (when successful) +- `float $accuracy` - Accuracy in meters (when successful) +- `int $timestamp` - Unix timestamp of location fix +- `string $provider` - Location provider used (GPS, network, etc.) +- `string $error` - Error message (when unsuccessful) + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Geolocation\LocationReceived; + +#[On('native:'.LocationReceived::class)] +public function handleLocationReceived( + $success = null, + $latitude = null, + $longitude = null, + $accuracy = null, + $timestamp = null, + $provider = null, + $error = null +) { + // ... +} +``` + +### `PermissionStatusReceived` + +Fired when permission status is checked. + +**Event Parameters:** +- `string $location` - Overall location permission status +- `string $coarseLocation` - Coarse location permission status +- `string $fineLocation` - Fine location permission status + +**Permission Values:** +- `'granted'` - Permission is granted +- `'denied'` - Permission is denied +- `'not_determined'` - Permission not yet requested + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Geolocation\PermissionStatusReceived; + +#[On('native:'.PermissionStatusReceived::class)] +public function handlePermissionStatus($location, $coarseLocation, $fineLocation) +{ + // ... +} +``` + +### `PermissionRequestResult` + +Fired when a permission request completes. + +**Event Parameters:** +- `string $location` - Overall location permission result +- `string $coarseLocation` - Coarse location permission result +- `string $fineLocation` - Fine location permission result +- `string $message` - Optional message (for permanently denied) +- `bool $needsSettings` - Whether user needs to go to Settings + +**Special Values:** +- `'permanently_denied'` - User has permanently denied permission + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\Geolocation\PermissionRequestResult; + +#[On('native:' . PermissionRequestResult::class)] +public function handlePermissionRequest($location, $coarseLocation, $fineLocation, $message = null, $needsSettings = null) +{ + if ($location === 'permanently_denied') { + $this->error = 'Location permission permanently denied. Please enable in Settings.'; + } elseif ($coarseLocation === 'granted' || $fineLocation === 'granted') { + $this->getCurrentLocation(); + } else { + $this->error = 'Location permission is required for this feature.'; + } +} +``` + +## Privacy Considerations + +- **Explain why** you need location access before requesting +- **Request at the right time** - when the feature is actually needed +- **Respect denials** - provide alternative functionality when possible +- **Use appropriate accuracy** - don't request fine location if coarse is sufficient +- **Limit frequency** - don't request location updates constantly + +### Performance Considerations +- **Battery Usage** - GPS uses more battery than network location +- **Time to Fix** - GPS takes longer for initial position +- **Indoor Accuracy** - GPS may not work well indoors +- **Caching** - Consider caching recent locations for better UX + diff --git a/resources/views/docs/mobile/2/apis/haptics.md b/resources/views/docs/mobile/2/apis/haptics.md new file mode 100644 index 00000000..2ec5c28b --- /dev/null +++ b/resources/views/docs/mobile/2/apis/haptics.md @@ -0,0 +1,29 @@ +--- +title: Haptics +order: 500 +--- + +## Overview + +The Haptics API provides access to the device's vibration and haptic feedback system for tactile user interactions. + +```php +use Native\Mobile\Facades\Haptics; +``` + +## Methods + +### `vibrate()` + +Triggers device vibration for tactile feedback. + +**Returns:** `void` + +```php +Haptics::vibrate(); +``` + +**Use haptics for:** Button presses, form validation, important notifications, game events. + +**Avoid haptics for:** Frequent events, background processes, minor updates. + diff --git a/resources/views/docs/mobile/2/apis/push-notifications.md b/resources/views/docs/mobile/2/apis/push-notifications.md new file mode 100644 index 00000000..62644eda --- /dev/null +++ b/resources/views/docs/mobile/2/apis/push-notifications.md @@ -0,0 +1,63 @@ +--- +title: PushNotifications +order: 600 +--- + +## Overview + +The PushNotifications API handles device registration for Firebase Cloud Messaging to receive push notifications. + +```php +use Native\Mobile\Facades\PushNotifications; +``` + +## Methods + +### `enroll()` + +Requests permission and enrolls the device for push notifications. + +**Returns:** `void` + +### `getToken()` + +Retrieves the current push notification token for this device. + +**Returns:** `string|null` - The FCM token, or `null` if not available + +## Events + +### `TokenGenerated` + +Fired when a push notification token is successfully generated. + +**Payload:** `string $token` - The FCM token for this device + +```php +use Livewire\Attributes\On; +use Native\Mobile\Events\PushNotification\TokenGenerated; + +#[On('native:'.TokenGenerated::class)] +public function handlePushToken(string $token) +{ + // Send token to your backend + $this->sendTokenToServer($token); +} +``` + +## Permission Flow + +1. User taps "Enable Notifications" +2. App calls `enroll()` +3. System shows permission dialog +4. If granted, FCM generates token +5. `TokenGenerated` event fires with token +6. App sends token to backend +7. Backend stores token for user +8. Server can now send notifications to this device + +## Best Practices + +- Request permission at the right time (not immediately on app launch) +- Explain the value of notifications to users +- Handle permission denial gracefully diff --git a/resources/views/docs/mobile/2/apis/qrcode.md b/resources/views/docs/mobile/2/apis/qrcode.md new file mode 100644 index 00000000..b1f2e187 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/qrcode.md @@ -0,0 +1,91 @@ +--- +title: QR Code Scanner +order: 350 +--- + +## Overview + +The QR Code Scanner API provides cross-platform barcode scanning capabilities through a native camera interface. + +```php +use Native\Mobile\Facades\Scanner; +use Native\Mobile\Events\QrCode\Scanned; +``` + +## Basic Usage + +```php +// Open scanner +Scanner::scan(); + +// Listen for scan results +#[On('native:'.Scanned::class)] +public function handleScan($data, $format, $id = null) +{ + Dialog::toast("Scanned: {$data}"); +} +``` + +## Configuration Methods + +### `prompt(string $prompt)` + +Set custom prompt text displayed on the scanner screen. + +```php +Scanner::scan()->prompt('Scan product barcode'); +``` + +### `continuous(bool $continuous = true)` + +Keep scanner open to scan multiple codes. Default is `false` (closes after first scan). + +```php +Scanner::scan()->continuous(true); +``` + +### `formats(array $formats)` + +Specify which barcode formats to scan. Default is `['qr']`. + +**Available formats:** `qr`, `ean13`, `ean8`, `code128`, `code39`, `upca`, `upce`, `all` + +```php +Scanner::scan()->formats(['qr', 'ean13', 'code128']); +``` + +### `id(string $id)` + +Set a unique identifier for the scan session. Useful for handling different scan contexts. + +```php +Scanner::scan()->id('checkout-scanner'); +``` + +## Events + +### `Scanned` + +Fired when a barcode is successfully scanned. + +**Properties:** +- `string $data` - The decoded barcode data +- `string $format` - The barcode format +- `string|null $id` - The scan session ID (if set) + +```php +#[On('native:'.Scanned::class)] +public function handleScan($data, $format, $id = null) +{ + if ($id === 'product-scanner') { + $this->addProduct($data); + } +} +``` + +## Platform Support + +- **Android:** ML Kit Barcode Scanning (API 21+) +- **iOS:** AVFoundation (iOS 13.0+) + +Camera permissions are handled automatically on both platforms. \ No newline at end of file diff --git a/resources/views/docs/mobile/2/apis/secure-storage.md b/resources/views/docs/mobile/2/apis/secure-storage.md new file mode 100644 index 00000000..14256a6e --- /dev/null +++ b/resources/views/docs/mobile/2/apis/secure-storage.md @@ -0,0 +1,87 @@ +--- +title: SecureStorage +order: 700 +--- + +## Overview + +The SecureStorage API provides secure storage using the device's native keychain (iOS) or keystore (Android). It's +ideal for storing sensitive data like tokens, passwords, and user credentials. + +```php +use Native\Mobile\Facades\SecureStorage; +``` + +## Methods + +### `set()` + +Stores a secure value in the native keychain or keystore. + +**Parameters:** +- `string $key` - The key to store the value under +- `string|null $value` - The value to store securely + +**Returns:** `bool` - `true` if successfully stored, `false` otherwise + +```php +SecureStorage::set('api_token', 'abc123xyz'); +``` + +### `get()` + +Retrieves a secure value from the native keychain or keystore. + +**Parameters:** +- `string $key` - The key to retrieve the value for + +**Returns:** `string|null` - The stored value or `null` if not found + +```php +$token = SecureStorage::get('api_token'); +``` + +### `delete()` + +Deletes a secure value from the native keychain or keystore. + +**Parameters:** +- `string $key` - The key to delete the value for + +**Returns:** `bool` - `true` if successfully deleted, `false` otherwise + +## Platform Implementation + +### iOS - Keychain Services +- Uses the iOS Keychain Services API +- Data is encrypted and tied to your app's bundle ID +- Survives app deletion and reinstallation if iCloud Keychain is enabled +- Protected by device passcode/biometrics + +### Android - Keystore +- Uses Android Keystore system +- Hardware-backed encryption when available +- Data is automatically deleted when app is uninstalled +- Protected by device lock screen + +## Security Features + +- **Encryption:** All data is automatically encrypted +- **App Isolation:** Data is only accessible by your app +- **System Protection:** Protected by device authentication +- **Tamper Resistance:** Hardware-backed security when available + +## What to Store +- API tokens and refresh tokens +- User credentials (if necessary) +- Encryption keys +- Sensitive user preferences +- Two-factor authentication secrets + +## What NOT to Store +- Large amounts of data (use encrypted database instead) +- Non-sensitive data +- Temporary data +- Cached content + + diff --git a/resources/views/docs/mobile/2/apis/system.md b/resources/views/docs/mobile/2/apis/system.md new file mode 100644 index 00000000..de949e96 --- /dev/null +++ b/resources/views/docs/mobile/2/apis/system.md @@ -0,0 +1,36 @@ +--- +title: System +order: 800 +--- + +## Overview + +The System API provides access to basic system functions like flashlight control. + +```php +use Native\Mobile\Facades\System; +``` + +## Methods + +### `flashlight()` + +Toggles the device flashlight (camera flash LED) on and off. + +**Returns:** `void` + +```php +System::flashlight(); // Toggle flashlight state +``` + +### `isIos()` + +Determines if the current device is running iOS. + +**Returns:** `true` if iOS, `false` otherwise + +### `isAndroid()` + +Determines if the current device is running Android. + +**Returns:** `true` if Android, `false` otherwise diff --git a/resources/views/docs/mobile/2/concepts/_index.md b/resources/views/docs/mobile/2/concepts/_index.md new file mode 100644 index 00000000..97e3b3a0 --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/_index.md @@ -0,0 +1,4 @@ +--- +title: Concepts +order: 3 +--- diff --git a/resources/views/docs/mobile/2/concepts/ci-cd.md b/resources/views/docs/mobile/2/concepts/ci-cd.md new file mode 100644 index 00000000..0e05bd2c --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/ci-cd.md @@ -0,0 +1,159 @@ +--- +title: CI/CD Integration +order: 500 +--- + +## Overview + +NativePHP for Mobile provides robust CLI commands designed for automated CI/CD environments. With proper configuration, +you can build, package, and deploy mobile apps without manual intervention. + +## Key Commands for CI/CD + +### Installation Command + +Install NativePHP dependencies in automated environments: + +```shell +# Install Android platform, overwriting existing files +php artisan native:install android --force --no-tty + +# Install with ICU support for Filament/intl features +php artisan native:install android --force --with-icu + +# Install both platforms +php artisan native:install both --force +``` + +### Build Commands + +Build your app for different environments: + +```shell +# Build debug version (development) +php artisan native:run android --build=debug --no-tty + +# Build release version (production) +php artisan native:run android --build=release --no-tty + +# Build app bundle for Play Store +php artisan native:run android --build=bundle --no-tty +``` + +### Packaging Command + +Package signed releases for distribution: + +```bash +# Package signed APK using environment variables +php artisan native:package android --build-type=release --output=/artifacts --no-tty + +# Package signed App Bundle for Play Store +php artisan native:package android --build-type=bundle --output=/artifacts --no-tty +``` + +## Environment Variables + +Store sensitive signing information in environment variables: + +```bash +# Android Signing +ANDROID_KEYSTORE_FILE="/path/to/keystore.jks" +ANDROID_KEYSTORE_PASSWORD="your-keystore-password" +ANDROID_KEY_ALIAS="your-key-alias" +ANDROID_KEY_PASSWORD="your-key-password" +``` + +## Command Line Options + +### `--no-tty` Flag +Essential for CI/CD environments where TTY is not available: +- Disables interactive prompts +- Provides non-interactive output +- Shows build progress without real-time updates +- Required for most automated environments + +### `--force` Flag +Overwrites existing files and directories: +- Useful for clean builds in CI +- Ensures fresh installation of NativePHP scaffolding +- Prevents build failures from existing files +- Do this whenever you are updating the `nativephp/mobile` package. + +### Build Types +- `--build=debug`: Development builds with debugging enabled +- `--build=release`: Production builds optimized for distribution +- `--build=bundle`: App bundles for Play Store distribution + +## Signing Configuration + +### Using Command Line Options +```bash +php artisan native:package android \ + --build-type=release \ + --keystore=/path/to/keystore.jks \ + --keystore-password=your-password \ + --key-alias=your-alias \ + --key-password=your-key-password \ + --output=./artifacts \ + --no-tty +``` + +### Using Environment Variables (Recommended) +```bash +# Set environment variables in CI +export ANDROID_KEYSTORE_FILE="/path/to/keystore.jks" +export ANDROID_KEYSTORE_PASSWORD="your-password" +export ANDROID_KEY_ALIAS="your-alias" +export ANDROID_KEY_PASSWORD="your-key-password" + +# Run packaging command +php artisan native:package android --build-type=release --output=./artifacts --no-tty +``` + +## Common CI Workflows + +### Development Pipeline +1. Install dependencies: `composer install` +2. Setup environment: copy `.env`, generate key +3. Install NativePHP: `native:install android --force` +4. Build debug: `native:run android --build=debug --no-tty` + +### Release Pipeline +1. Install dependencies: `composer install --no-dev --optimize-autoloader` +2. Setup environment with production settings +3. Install NativePHP: `native:install android --force --with-icu` +4. Package release: `native:package android --build-type=release --no-tty` + +### Play Store Pipeline +1. Same as release pipeline through step 3 +2. Package bundle: `native:package android --build-type=bundle --no-tty` +3. Upload to Play Console + +## Error Handling + +NativePHP commands provide proper exit codes for CI/CD: +- `0`: Success +- `1`: General error +- Build errors are logged and reported + +Monitor build logs for: +- Compilation errors +- Signing failures +- Missing dependencies +- Permission issues + +## Performance Tips + +### Caching +Cache these directories in CI for faster builds: +- `vendor/` (Composer dependencies) +- `nativephp/android/` (Android project) +- Android SDK components + +### Optimization +- Use `--no-dev` for production Composer installs +- Enable Composer autoloader optimization +- Minimize included files with cleanup configuration + +The `--no-tty` flag and environment variable support make NativePHP Mobile well-suited for modern CI/CD pipelines, enabling fully automated mobile app builds and deployments. diff --git a/resources/views/docs/mobile/2/concepts/databases.md b/resources/views/docs/mobile/2/concepts/databases.md new file mode 100644 index 00000000..b0270508 --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/databases.md @@ -0,0 +1,149 @@ +--- +title: Databases +order: 200 +--- + +## Working with Databases + +You'll almost certainly want your application to persist structured data. For this, NativePHP supports +[SQLite](https://sqlite.org/), which works on both iOS and Android devices. + +You can interact with SQLite from PHP in whichever way you're used to. + +## Configuration + +You do not need to do anything special to configure your application to use SQLite. NativePHP will automatically: +- Switch to using SQLite when building your application. +- Create the database for you in the app container. +- Run your migrations each time your app starts, as needed. + +## Migrations + +When writing migrations, you need to consider any special recommendations for working with SQLite. + +For example, prior to Laravel 11, SQLite foreign key constraints are turned off by default. If your application relies +upon foreign key constraints, [you need to enable SQLite support for them](https://laravel.com/docs/database#configuration) before running your migrations. + +**It's important to test your migrations on [prod builds](/docs/mobile/1/getting-started/development#releasing) +before releasing updates!** You don't want to accidentally delete your user's data when they update your app. + +## Seeding data with migrations + +Migrations are the perfect mechanism for seeding data in mobile applications. They provide the natural behavior you +want for data seeding: + +- **Run once**: Each migration runs exactly once per installation. +- **Tracked**: Laravel tracks which migrations have been executed. +- **Versioned**: New app versions can include new data seeding migrations. +- **Reversible**: You can create migrations to remove or update seed data. + +### Creating seed migrations + +Create dedicated migrations for seeding data: + +```shell +php artisan make:migration seed_app_settings +``` + +```php +use Illuminate\Database\Migrations\Migration; +use Illuminate\Support\Facades\DB; + +return new class extends Migration +{ + public function up() + { + DB::table('categories')->insert([ + ['name' => 'Work', 'color' => '#3B82F6'], + ['name' => 'Personal', 'color' => '#10B981'], + ]); + } +}; +``` + +### Test thoroughly + +This is the most important step when releasing new versions of your app, especially with new migrations. + +Your migrations should work both for users who are installing your app for the first time (or re-installing) _and_ +users who have updated your app to a new release. + +Make sure you test your migrations under the different scenarios that your users' databases are likely to be in. + +## Things to note + +- As your app is installed on a separate device, you do not have remote access to the database. +- If a user deletes your application from their device, any databases are also deleted. + +## Can I get MySQL/Postgres/other support? + +No. + +SQLite being the only supported database driver is a deliberate security decision to prevent developers from +accidentally embedding production database credentials directly in mobile applications. Why? + +- Mobile apps are distributed to user devices and can be reverse-engineered. +- Database credentials embedded in apps may be accessible to anyone with the app binary. +- Direct database connections bypass important security layers like rate limiting and access controls. +- Network connectivity issues make direct database connections unreliable from mobile devices and can be troublesome + for your database to handle. + +## API-first + +If a key part of your application relies on syncing data between a central database and your client apps, we strongly +recommend that you do so via a secure API backend that your mobile app can communicate with. + +This provides multiple security and architectural benefits: + +**Security Benefits:** +- Database credentials never leave your server +- Implement proper authentication and authorization +- Rate limiting and request validation +- Audit logs for all data access +- Ability to revoke access instantly + +**Technical Benefits:** +- Better error handling and offline support +- Easier to scale and maintain +- Version your API for backward compatibility +- Transform data specifically for mobile consumption + +### Securing your API + +For the same reasons that you shouldn't share database credentials in your `.env` file or elsewhere in your app code, +you shouldn't store API keys or tokens either. + +If anything, you should provide a client key that **only** allows client apps to request tokens. Once you have +authenticated your user, you can pass an access token back to your mobile app and use this for communicating with your +API. + +Store these tokens on your users' devices securely with the [`SecureStorage`](/docs/mobile/1/apis/secure-storage) API. + +It's a good practice to ensure these tokens have high entropy so that they are very hard to guess and a short lifespan. +Generating tokens is cheap; leaking personal customer data can get _very_ expensive! + +Use industry-standard tools like OAuth-2.0-based providers, Laravel Passport, or Laravel Sanctum. + + + +#### Considerations + +In your mobile apps: + +- Always store API tokens using `SecureStorage` +- Use HTTPS for all API communications +- Cache data locally using SQLite for offline functionality +- Check for connectivity before making API calls + +And on the API side: + +- Use token-based authentication +- Implement rate limiting to prevent abuse +- Validate and sanitize all input data +- Use HTTPS with proper SSL certificates +- Log all authentication attempts and API access diff --git a/resources/views/docs/mobile/2/concepts/deep-links.md b/resources/views/docs/mobile/2/concepts/deep-links.md new file mode 100644 index 00000000..3bb8a305 --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/deep-links.md @@ -0,0 +1,92 @@ +--- +title: Deep Links +order: 300 +--- + +## Overview + +NativePHP for Mobile supports **deep linking** into your app via Custom URL Schemes and Associated Domains: + +- **Custom URL Scheme** + ``` + myapp://some/path + ``` +- **Associated Domains** (a.k.a. Universal Links on iOS, App Links on Android) + ``` + https://example.net/some/path + ``` + +In each case, your app can be opened directly at the route matching `/some/path`. + +Each method has its use cases, and NativePHP handles all the platform-specific configuration automatically when you +provide the proper environment variables. + +You can even use both approaches at the same time in a single app! + +## Custom URL Scheme + +Custom URL schemes are a great way to allow apps to pass data between themselves. If your app is installed when a user +uses a deep link that incorporates your custom scheme, your app will open immediately to the desired route. + +But note that custom URL schemes can only work when your app has been installed and cannot aid in app discovery. If a +user interacts with URL with a custom scheme for an app they don't have installed, there will be no prompt to install +an app that can load that URL. + +To enable your app's custom URL scheme, define it in your `.env`: + +```dotenv +NATIVEPHP_DEEPLINK_SCHEME=myapp +``` + +You should choose a scheme that is unique to your app to avoid confusion with other apps. Note that some schemes are +reserved by the system and cannot be used (e.g. `https`). + +## Associated domains + +Universal Links/App Links allow real HTTPS URLs to open your app instead of in a web browser, if the app is installed. +If the app is not installed, the URL will load as normal in the browser. + +This flow increases the opportunity for app discovery dramatically and provides a much better overall user experience. + +### How it works + +1. You must prove to the operating system on the user's device that your app is legitimately associated with the domain + you are trying to redirect by hosting special files on your server: + - `.well-known/apple-app-site-association` (for iOS) + - `.well-known/assetlinks.json` (for Android) +2. The mobile OS reads these files to verify the link association +3. Once verified, tapping a real URL will open your app instead of opening it in the user's browser + +**NativePHP handles all the technical setup automatically** - you just need to host the verification files and +configure your domain correctly. + +To enable an app-associated domain, define it in your `.env`: + +```dotenv +NATIVEPHP_DEEPLINK_HOST=example.net +``` + +## Testing & troubleshooting + +Associated Domains do not usually work in simulators. Testing on a real device that connects to a publicly-accessible +server for verification is often the best way to ensure these are operating correctly. + +If you are experiencing issues getting your associated domain to open your app, try: +- Completely deleting and reinstalling the app. Registration verifications (including failures) are often cached + against the app. +- Validating that your associated domain verification files are formatted correctly and contain the correct data. + +There is usually no such limitation for Custom URL Schemes. + +## Use cases + +Deep linking is great for bringing users from another context directly to a key place in your app. Universal/App Links +are usually the more appropriate choice for this because of their flexibility in falling back to simple loading a URL +in the browser. + +They're also more likely to behave the same across both platforms. + +Then you could use Universal/App Links in: +- NFC tags +- QR codes +- Email/SMS marketing diff --git a/resources/views/docs/mobile/2/concepts/push-notifications.md b/resources/views/docs/mobile/2/concepts/push-notifications.md new file mode 100644 index 00000000..855a3dcd --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/push-notifications.md @@ -0,0 +1,93 @@ +--- +title: Push Notifications +order: 400 +--- + +## Overview + +NativePHP for Mobile uses Firebase Cloud Messaging (FCM) to send push notifications to your users on both iOS and +Android devices. + +To send a push notification to a user, your app must request a token. That token must then be stored securely (ideally +on a server application via a secure API) and associated with that user/device. + +Requesting push notification will trigger an alert for the user to either approve or deny your request. If they approve, +your app will receive the token. + +When you want to send a notification to that user, you pass this token along with a request to the FCM service and +Firebase handles sending the message to the right device. + + + +## Firebase + +1. Create a [Firebase](https://firebase.google.com/) account +2. Create a project +3. Download the `google-services.json` file (for Android) and `GoogleService-Info.plist` file (for iOS) +4. These files contain the configuration for your app and is used by the Firebase SDK to retrieve tokens for each device + +Place these files in the root of your application and NativePHP will automatically handle setting them up appropriately +for each platform. + +You can ignore Firebase's further setup instructions as this is already taken care of by NativePHP. + +### Service account + +For sending push notifications from your server-side application, you'll also need a Firebase service account: + +1. Go to your Firebase Console β†’ Project Settings β†’ Service Accounts +2. Click "Generate New Private Key" to download the service account JSON file +3. Save this file as `fcm-service-account.json` somewhere safe in your server application + +## Getting push tokens + +It's common practice to request push notification permissions during app bootup as tokens can change when: +- The app is restored on a new device +- The app data is restored from backup +- The app is updated +- Other internal FCM operations + +To request a token, use the `PushNotifications::getToken()` method: + +```php +use Native\Mobile\Facades\PushNotifications; + +PushNotifications::getToken(); +``` + +If the user has approved your app to use push notifications and the request to FCM succeeded, a `TokenGenerated` event +will fire. + +Listen for this event to receive the token. Here's an example in a Livewire component: + +```php +use App\Services\APIService; +use Livewire\Attributes\On; +use Native\Mobile\Facades\PushNotifications; +use Native\Mobile\Events\PushNotification\TokenGenerated; + +class PushNotifications extends Component +{ + #[On('native:'.TokenGenerated::class)] + public function storePushToken(APIService $api, string $token) + { + $api->storePushToken($token); + } +} +``` + +## Sending push notifications + +Once you have a token, you may use it from your server-side applications to trigger Push Notifications directly to your +user's device. + + diff --git a/resources/views/docs/mobile/2/concepts/security.md b/resources/views/docs/mobile/2/concepts/security.md new file mode 100644 index 00000000..fcb2e777 --- /dev/null +++ b/resources/views/docs/mobile/2/concepts/security.md @@ -0,0 +1,104 @@ +--- +title: Security +order: 100 +--- + +## Security + +Although NativePHP tries to make it as easy as possible to make your application secure, it is your responsibility to +protect your users. + +### Secrets and .env + +As your application is being installed on systems outside your/your organisation's control, it is important to think +of the environment that it's in as _potentially_ hostile, which is to say that any secrets, passwords or keys +could fall into the hands of someone who might try to abuse them. + +This means you should, where possible, use unique keys for each installation, preferring to generate these at first-run +or on every run rather than sharing the same key for every user across many installations. + +Especially if your application is communicating with any private APIs over the network, we highly recommend that your +application and any API use a robust and secure authentication protocol, such as OAuth2, that enables you to create and +distribute unique and expiring tokens (an expiration date less than 48 hours in the future is recommended) with a high +level of entropy, as this makes them hard to guess and hard to abuse. + +**Always use HTTPS.** + +If your application allows users to connect _their own_ API keys for a service, you should treat these keys with great +care. If you choose to store them anywhere (either in a file or +[Database](databases)), make sure you store them +[encrypted](../the-basics/system#encryption-decryption) and decrypt them only when needed. + +## Secure Storage + +NativePHP provides access to your users' device's native Keystore/Keychain through the +[`SecureStorage`](/docs/apis/secure-storage) facade, which +allow you to store small amounts of data in a secure way. + +The device's secure storage encrypts and decrypts data on the fly and that means you can safely rely on it to store +critical things like API tokens, keeping your users and your systems safe. + +This data is only accessible by your app and is persisted beyond the lifetime of your app, so it will still be available +the next time your app is open. + +### Why not use the Laravel `Crypt` facade? + +By default, the `Crypt` facade - and by extension the `encrypt` and `decrypt` helper functions - all rely on the +`APP_KEY` value set in your `.env` file. + +We _will_ use Laravel's underlying `Encryption` class, but you should avoid using these helpers directly. + +In the context of distributed apps, the `APP_KEY` is shipped _with_ your app and therefore isn't secure. Anyone who +knows where to look for it will be able to find it. Then any data encrypted with it is no better off than if it was +stored in plain text. + +Also, it will be the same key for every user, and this presents a considerable risk. + +What you really want is a **unique key for each user**, and for that you really need to generate your encryption key +once your app is installed on your user's device. + +You could do this and update the `.env` file, but it would still be stored in a way that an attacker may be able to +exploit. + +A better approach is to generate a secure key the first time your app opens, place that key in Secure Storage, and +then use that key to encrypt your other data before storage: + +```php +use Illuminate\Encryption\Encrypter; +use Illuminate\Support\Facades\Storage; +use Native\Mobile\Facades\SecureStorage; + +function generateRandomKey() +{ + return base64_encode( + Encrypter::generateKey(config('app.cipher')) + ); +} + +$encryptionKey = SecureStorage::get('encryption_key'); + +if (! $encryptionKey) { + SecureStorage::set('encryption_key', $encryptionKey = generateRandomKey()); +} + +$mobileEncrypter = new Encrypter($encryptionKey); + +$encryptedContents = $mobileEncrypter->encrypt( + $request->file('super_private_file') +); + +Storage::put('my_secure_file.pdf', $encryptedContents); +``` + +And then decrypt it later: + +```php +$decryptedContents = $mobileEncrypter->decrypt( + Storage::get('my_secure_file.pdf') +); +``` + +### Secure Storage vs Database/Files + +Secure Storage is only meant for small amounts of text data, usually no more than a few KBs. If you need to store +larger amounts of data or files, you should store this in a database or as a file. diff --git a/resources/views/docs/mobile/2/edge-components/_index.md b/resources/views/docs/mobile/2/edge-components/_index.md new file mode 100644 index 00000000..c720f144 --- /dev/null +++ b/resources/views/docs/mobile/2/edge-components/_index.md @@ -0,0 +1,4 @@ +--- +title: EDGE Components +order: 5 +--- diff --git a/resources/views/docs/mobile/2/edge-components/bottom-nav.md b/resources/views/docs/mobile/2/edge-components/bottom-nav.md new file mode 100644 index 00000000..6b52b78a --- /dev/null +++ b/resources/views/docs/mobile/2/edge-components/bottom-nav.md @@ -0,0 +1,46 @@ +--- +title: Bottom Navigation +order: 100 +--- + +## Overview + +A bottom navigation bar with up to 5 items for primary navigation. + +@verbatim +```blade + + + + +``` +@endverbatim + +## BottomNav Props + +- `label-visibility` - `"labeled"` (default), `"selected"`, or `"unlabeled"` +- `dark` - Force dark mode styling (optional) + +## BottomNavItem Props + +- `id` - Unique identifier (required) +- `icon` - Material icon name (required) +- `label` - Display text (required) +- `url` - Navigation URL (required) +- `active` - Highlight as active (default: `false`) +- `badge` - Badge text/number (optional) +- `badge-color` - Badge background color hex (optional) +- `news` - Show "new" indicator dot (default: `false`) diff --git a/resources/views/docs/mobile/2/edge-components/fab.md b/resources/views/docs/mobile/2/edge-components/fab.md new file mode 100644 index 00000000..27812015 --- /dev/null +++ b/resources/views/docs/mobile/2/edge-components/fab.md @@ -0,0 +1,42 @@ +--- +title: Floating Action Button +order: 300 +--- + +## Overview + +A floating action button (FAB) that sits above the content. + +@verbatim +```blade + +``` +@endverbatim + +## Props + +- `icon` - Material icon name (required) +- `label` - Button text (optional, shows extended FAB) +- `url` - Navigation URL (optional) +- `event` - Event to dispatch (optional) +- `size` - `"small"`, `"regular"` (default), or `"large"` +- `position` - `"start"`, `"center"`, or `"end"` (default) +- `bottom-offset` - Distance from bottom in pixels (optional) +- `elevation` - Shadow depth (optional) +- `corner-radius` - Border radius in pixels (optional) +- `container-color` - Background hex (optional) +- `content-color` - Icon/text hex (optional) + +## Material Icons + +All components use Material Symbols icons. Common icons include: + +`home`, `person`, `settings`, `search`, `menu`, `add`, `edit`, `delete`, `favorite`, `share`, `notifications`, `inbox`, `shopping_cart`, `help`, `info`, `arrow_back`, `close`, `check`, `more_vert` + +Browse all icons at [Google Fonts Icons](https://fonts.google.com/icons). diff --git a/resources/views/docs/mobile/2/edge-components/side-nav.md b/resources/views/docs/mobile/2/edge-components/side-nav.md new file mode 100644 index 00000000..74d6054a --- /dev/null +++ b/resources/views/docs/mobile/2/edge-components/side-nav.md @@ -0,0 +1,97 @@ +--- +title: Side Navigation +order: 400 +--- + +## Overview + +A slide-out navigation drawer with support for groups, headers, and dividers. + +@verbatim +```blade + + + + + + + + + + + + + + +``` +@endverbatim + +## SideNav Props + +- `gestures-enabled` - Swipe to open (default: `false`) +- `label-visibility` - `"labeled"` (default), `"selected"`, or `"unlabeled"` +- `dark` - Force dark mode (optional) + +## SideNavHeader Props + +- `title` - Header title (optional) +- `subtitle` - Subtext (optional) +- `icon` - Material icon (optional) +- `image-url` - Header image URL (optional) +- `background-color` - Background hex (optional) +- `event` - Click event (optional) +- `show-close-button` - Show close X (default: `true`) +- `pinned` - Keep header visible when scrolling (default: `false`) + +## SideNavItem Props + +- `id` - Unique identifier (required) +- `label` - Display text (required) +- `icon` - Material icon (required) +- `url` - Navigation URL (required) +- `active` - Highlight as active (default: `false`) +- `badge` - Badge text (optional) +- `badge-color` - Badge color hex (optional) +- `open-in-browser` - Open URL externally (default: `false`) + +## SideNavGroup Props + +- `heading` - Group title (required) +- `expanded` - Initially expanded (default: `false`) +- `icon` - Material icon (optional) + +## HorizontalDivider + +Add visual separators between navigation items. + +@verbatim +```blade + +``` +@endverbatim diff --git a/resources/views/docs/mobile/2/edge-components/top-bar.md b/resources/views/docs/mobile/2/edge-components/top-bar.md new file mode 100644 index 00000000..e106f67c --- /dev/null +++ b/resources/views/docs/mobile/2/edge-components/top-bar.md @@ -0,0 +1,42 @@ +--- +title: Top Bar +order: 200 +--- + +## Overview + +A top app bar with title and action buttons. + +@verbatim +```blade + + + + +``` +@endverbatim + +## TopBar Props + +- `title` - Bar title (required) +- `subtitle` - Secondary text (optional) +- `show-navigation-icon` - Show back/menu button (default: `true`) +- `background-color` - Background hex color (optional) +- `text-color` - Text hex color (optional) +- `elevation` - Shadow depth 0-24 (optional) + +## TopBarAction Props + +- `id` - Unique identifier (required) +- `icon` - Material icon name (required) +- `label` - Accessibility label (optional) +- `url` - Navigation URL (optional) +- `event` - Event to dispatch (optional) diff --git a/resources/views/docs/mobile/2/getting-started/_index.md b/resources/views/docs/mobile/2/getting-started/_index.md new file mode 100644 index 00000000..5c684744 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/_index.md @@ -0,0 +1,4 @@ +--- +title: Getting Started +order: 1 +--- \ No newline at end of file diff --git a/resources/views/docs/mobile/2/getting-started/configuration.md b/resources/views/docs/mobile/2/getting-started/configuration.md new file mode 100644 index 00000000..ec4c727d --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/configuration.md @@ -0,0 +1,139 @@ +--- +title: Configuration +order: 200 +--- + +## Overview + +NativePHP for Mobile is designed so that most configuration happens **inside your Laravel application**, without +requiring you to manually open Xcode or Android Studio. + +This page explains the key configuration points you can control through Laravel. + +## The `nativephp.php` Config File + +The `config/nativephp.php` config file contains a number of useful options. + +NativePHP uses sensible defaults and makes several assumptions based on default installations for tools required to +build and run apps from your computer. + +You can override these defaults by editing the `nativephp.php` config file in your Laravel project, and in many case +simply by changing environment variables. + +```dotenv +NATIVEPHP_APP_VERSION +NATIVEPHP_APP_VERSION_CODE +NATIVEPHP_APP_ID +NATIVEPHP_DEEPLINK_SCHEME +NATIVEPHP_DEEPLINK_HOST +NATIVEPHP_APP_AUTHOR +NATIVEPHP_GRADLE_PATH +NATIVEPHP_ANDROID_SDK_LOCATION +``` + +## `NATIVEPHP_APP_ID` + +You must set your app ID to something unique. A common practice is to use a reverse-DNS-style name, e.g. +`com.yourcompany.yourapp`. + +Your app ID (also known as a *Bundle Identifier*) is a critical piece of identification across both Android and iOS +platforms. Different app IDs are treated as separate apps. + +And it is often referenced across multiple services, such as Apple Developer Center and the Google Play Console. + +So it's not something you want to be changing very often. + +## `NATIVEPHP_APP_VERSION` + +The `NATIVEPHP_APP_VERSION` environment variable controls your app's versioning behavior. + +When your app is compiling, NativePHP first copies the relevant Laravel files into a temporary directory, zips them up, +and embeds the archive into the native application. + +When your app boots, it checks the embedded version against the previously installed version to see if it needs to +extract the bundled Laravel application. + +If the versions match, the app uses the existing files without re-extracting the archive. + +To force your application to always install the latest version of your code - especially useful during development - +set this to `DEBUG`: + +```dotenv +NATIVEPHP_APP_VERSION=DEBUG +``` + +Note that this will make your application's boot up slightly slower as it must unpack the zip every time it loads. + +But this ensures that you can iterate quickly during development, while providing a faster, more stable experience for +end users once an app is published. + +## Cleanup `env` keys + +The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file before bundling. +This is useful for removing sensitive information like API keys or other secrets. + +## Cleanup `exclude_files` + +The `cleanup_exclude_files` array in the config file allows you to specify files and folders that should be removed before bundling. +This is useful for removing files like logs or other temporary files. + +## Permissions +In general, the app stores don't want your app to have permissions (a.k.a entitlements) it doesn't need. + +By default, all optional permissions are disabled. + +You may enable the features you intend to use simply by changing the value of the appropriate permission to `true`: + +```php + + 'permissions' => [ + + 'biometric' => true, + + ], +``` + +### Available permissions + +- `biometric` - Allows your application to use fingerprint or face-recognition hardware (with a fallback to PIN code) + to secure parts of your application. +- `camera` - Allows your application to request access to the device's camera, if present. Note that the user may deny + access and any camera functions will then result in a no-op. +- `nfc` - Allows your application to request access to the device's NFC reader, if present. +- `push_notifications` - Allows your application to request permissions to send push notifications. Note that the user + may deny this and any push notification functions will then result in a no-op. +- `location` - Allows your application to request access to the device's GPS receiver, if present. Note that the user + may deny this and any location functions will then result in a no-op. +- `vibrate` - In modern Android devices this is a requirement for most haptic feedback. +- `storage_read` - Grants your app access to read from device storage locations. +- `storage_write` - Allows your app to write to device storage. + +## Orientation + +NativePHP (as of v1.10.3) allows users to custom specific orientations per device through the config file. The config allows for granularity for iPad, iPhone and Android devices. Options for each device can be seen below. + +NOTE: if you want to disable iPad support completely simply apply `false` for each option. + +```php +'orientation' => [ + 'iPhone' => [ + 'portrait' => true, + 'upside_down' => false, + 'landscape_left' => false, + 'landscape_right' => false, + ], + 'iPad' => [ + 'portrait' => true, + 'upside_down' => false, + 'landscape_left' => false, + 'landscape_right' => false, + ], + 'android' => [ + 'portrait' => true, + 'upside_down' => false, + 'landscape_left' => false, + 'landscape_right' => false, + ], +], +``` + diff --git a/resources/views/docs/mobile/2/getting-started/development.md b/resources/views/docs/mobile/2/getting-started/development.md new file mode 100644 index 00000000..9ccaa5a9 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/development.md @@ -0,0 +1,201 @@ +--- +title: Development +order: 300 +--- + +Developing your NativePHP apps can be done in the browser, using workflows with which you're already familiar. + +This allows you to iterate rapidly on parts like the UI and major functionality, even using your favorite tools for +testing etc. + +But when you want to test _native_ features, then you must run your app on a real/emulated device. + +Whether you run your native app on an emulated or real device, it will always require compilation after changes have +been made. + + + +## Build your frontend + +If you're using Vite or similar tooling to build any part of your UI (e.g. for React/Vue, Tailwind etc), you'll need +to run your asset build command _before_ compiling your app. + +### Inertia on iOS + +Due to the way your apps are configured to work on iOS, we need to patch the Axios package to make Inertia work. + +We've tried to make this as straightforward as possible. Simply run: + +```shell +php artisan native:patch-inertia +``` + +This will backup your current `vite.config.js` and replace it with one that 'fixes' Axios. + +You will just need to copy over any specific config (plugins etc) from your old Vite config to this new one. + +Once that's done, you'll need to adjust your Vite build command for when you're creating iOS builds. _Only_ for iOS +builds. (If you try to run these builds on Android they probably won't work.) + +Add the `--mode=ios` to your build command. Run it before compiling your app for iOS. Here's an example using `npm`: + +```shell +npm run build -- --mode=ios +``` + +## Compile your app + +To compile and run your app, simply run: + +```shell +php artisan native:run --build=debug +``` + +This single command takes care of everything and allows you to run new builds of your application without having to +learn any new editors or platform-specific tools. + + + +## Working with Xcode or Android Studio + +On occasion, it is useful to compile your app from inside the target platform's dedicated development tools, Android +Studio and Xcode. + +If you're familiar with these tools, you can easily open the projects using the following Artisan command: + +```shell +php artisan native:open +``` + +## Hot Reloading + +We've tried to make compiling your apps as fast as possible, but when coming from the 'make a change; hit refresh'-world +of PHP development that we all love, compiling apps can feel like a slow and time-consuming process. + +So we've released hot reloading, which aims to make your development experience feel just like home. + +You can enable hot reloading by running the following command: + +```shell +php artisan native:watch {platform:ios|android} +``` + +This is useful during development for quickly testing changes without re-compiling your entire app. When you make +changes to any files in your Laravel app, the web view will be reloaded and your changes should show almost immediately. + +### Implementation + +The proper way to implement this is to first `run` your app on your device/emulator, then start HMR with `npm run dev` then in a separate terminal run the `native:watch` command. This will reload any Blade/Livewire files as well as any recompiled assets (css/js etc). + + + + +## Releasing + +To prepare your app for release, you should set the version number to a new version number that you have not used +before and increment the build number: + +```dotenv +NATIVEPHP_APP_VERSION=1.2.3 +NATIVEPHP_APP_VERSION_CODE=48 +``` + +### Versioning + +You have complete freedom in how you version your applications. You may use semantic versioning, codenames, +date-based versions, or any scheme that works for your project, team or business. + +Remember that your app versions are usually public-facing (e.g. in store listings and on-device settings and update +screens) and can be useful for customers to reference if they need to contact you for help and support. + +The build number is managed via the `NATIVEPHP_APP_VERSION` key in your `.env`. + +### Build numbers + +Both the Google Play Store and Apple App Store require your app's build number to increase for each release you submit. + +The build number is managed via the `NATIVEPHP_APP_VERSION_CODE` key in your `.env`. + +### Run a `release` build + +Then run a release build: + +```shell +php artisan native:run --build=release +``` + +This builds your application with various optimizations that reduce its overall size and improve its performance, such +as removing debugging code and unnecessary features (i.e. Composer dev dependencies). + +**You should test this build on a real device.** Once you're happy that everything is working as intended you can then +submit it to the stores for approval and distribution. + +- [Google Play Store submission guidelines](https://support.google.com/googleplay/android-developer/answer/9859152?hl=en-GB#zippy=%2Cmaximum-size-limit) +- [Apple App Store submission guidelines](https://developer.apple.com/ios/submit/) + + diff --git a/resources/views/docs/mobile/2/getting-started/environment-setup.md b/resources/views/docs/mobile/2/getting-started/environment-setup.md new file mode 100644 index 00000000..dce96acb --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/environment-setup.md @@ -0,0 +1,144 @@ +--- +title: Environment Setup +order: 100 +--- + +## Requirements + +1. PHP 8.3+ +2. Laravel 11+ +3. [A NativePHP for Mobile license](https://nativephp.com/mobile) + +If you don't already have PHP installed on your machine, the most painless way to get PHP up and running on Mac and +Windows is with [Laravel Herd](https://herd.laravel.com). It's fast and free! + +## iOS Requirements + + + +1. macOS (required - iOS development is only possible on a Mac) +2. [Xcode 16.0 or later](https://apps.apple.com/app/xcode/id497799835) +3. Xcode Command Line Tools +4. Homebrew & CocoaPods +5. _Optional_ iOS device for testing + +### Setting up iOS Development Environment + +1. **Install Xcode** + - Download from the [Mac App Store](https://apps.apple.com/app/xcode/id497799835) + - Minimum version: Xcode 16.0 + +2. **Install Xcode Command Line Tools** + ```shell + xcode-select --install + ``` + Verify installation: + ```shell + xcode-select -p + ``` + +3. **Install Homebrew** (if not already installed) + ```shell + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + ``` + +4. **Install CocoaPods** + ```shell + brew install cocoapods + ``` + Verify installation: + ```shell + pod --version + ``` + +### Apple Developer Account +You **do not** need to enroll in the [Apple Developer Program](https://developer.apple.com/programs/enroll/) ($99/year) +to develop and test your apps on a Simulator. However, you will need to enroll when you want to: +- Test your apps on real devices +- Distribute your apps via the App Store + +## Android Requirements + +1. [Android Studio 2024.2.1 or later](https://developer.android.com/studio) +2. Android SDK with API 33 or higher +3. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed. + + + +### Setting up Android Studio and SDK + +1. **Download and Install Android Studio** + - Download from the [Android Studio download page](https://developer.android.com/studio) + - Minimum version required: Android Studio 2024.2.1 + +2. **Install Android SDK** + - Open Android Studio + - Navigate to **Tools β†’ SDK Manager** + - In the **SDK Platforms** tab, install at least one Android SDK platform for API 33 or higher + - Latest stable version: Android 15 (API 35) + - You only need to install one API version to get started + - In the **SDK Tools** tab, ensure **Android SDK Build-Tools** and **Android SDK Platform-Tools** are installed + +That's it! Android Studio handles all the necessary configuration automatically. + +### Preparing for NativePHP + +1. Check that you can run `java -version` and `adb devices` from the terminal. +2. The following environment variables set: + +#### On macOS +```shell +# This isn't required if JAVA_HOME is already set in your environment variables (check using `printenv | grep JAVA_HOME`) +export JAVA_HOME=$(/usr/libexec/java_home -v 17) + +export ANDROID_HOME=$HOME/Library/Android/sdk +export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools +``` + +#### On Windows +The example below assumes default installation paths for the Android SDK and JDK: + +```shell +set ANDROID_HOME=C:\Users\yourname\AppData\Local\Android\Sdk +set PATH=%PATH%;%JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools + +# This isn't required if JAVA_HOME is already set in the Windows Env Variables +set JAVA_HOME=C:\Program Files\Microsoft\jdk-17.0.8.7-hotspot +``` + +### "No AVDs found" error +If you encounter this error, it means no Virtual Devices are configured in Android Studio. +To resolve it, open Android Studio, navigate to Virtual Devices, and create at least one device. + +## Testing on Real Devices + +You don't _need_ a physical iOS/Android device to compile and test your application, as NativePHP for Mobile supports +the iOS Simulator and Android emulators. However, we highly recommend that you test your application on a real device +before submitting to the Apple App Store and Google Play Store. + +### On iOS +If you want to run your app on a real iOS device, you need to make sure it is in +[Developer Mode](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device) +and that it's been added to your Apple Developer account as +[a registered device](https://developer.apple.com/account/resources/devices/list). + +### On Android +On Android you need to [enable developer options](https://developer.android.com/studio/debug/dev-options#enable) +and have USB debugging (ADB) enabled. diff --git a/resources/views/docs/mobile/2/getting-started/installation.md b/resources/views/docs/mobile/2/getting-started/installation.md new file mode 100644 index 00000000..d496acfe --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/installation.md @@ -0,0 +1,159 @@ +--- +title: Installation +order: 100 +--- + +## Get a license + +Before you begin, you will need to [purchase a license](/mobile). + +To make NativePHP for Mobile a reality has taken a lot of work and will continue to require even more. For this reason, +it's not open source, and you are not free to distribute or modify its source code. + +Your license fee goes straight back into the NativePHP project and community, enabling us to: +- Develop premium features for everyone. +- Provide first-class support. +- Sponsor our dependencies. +- Donate to our contributors. +- Support community events. +- Ensure that the whole NativePHP project remains viable for a long time to come. + +Thank you for supporting the project in this way! πŸ™ + +## Install the Composer package + + + +Once you have your license, you will need to add the following to your `composer.json`: + +```json +"repositories": [ + { + "type": "composer", + "url": "https://nativephp.composer.sh" + } +], +``` + +Then run: +```shell +composer require nativephp/mobile +``` + + + + +If this is the first time you're installing the package, you will be prompted to authenticate. Your username is the +email address you used when purchasing your license. Your password is your license key. + +This package contains all the libraries, classes, commands, and interfaces that your application will need to work with +iOS and Android. + +## Run the NativePHP installer + +**Before** running the `install` command, it is important to set the following variables in your `.env`: + +```dotenv +NATIVEPHP_APP_ID=com.yourcompany.yourapp +NATIVEPHP_APP_VERSION="DEBUG" +NATIVEPHP_APP_VERSION_CODE="1" +``` + +Find out more about these options in +[Configuration](/docs/getting-started/configuration#codenativephp-app-idcode). + + + + +```shell +php artisan native:install +``` + +The NativePHP installer takes care of setting up and configuring your Laravel application to work with iOS and Android. + +You may be prompted about whether you would like to install the ICU-enabled PHP binaries. You should install these if +your application relies on the `intl` PHP extension. + +If you don't need `intl` or are not sure, choose the default, non-ICU builds. + + + +### The `nativephp` Directory + +After running: `php artisan native:install` you’ll see a new `nativephp` directory at the root of your Laravel project +as well as a `config/nativephp.php` config file. + +The `nativephp` folder contains the native application project files needed to build your app for the desired platforms. + +You should not need to manually open or edit any native project files under normal circumstances. NativePHP handles +the heavy lifting for you. + +**You should treat this directory as ephemeral.** When upgrading the NativePHP package, it will be necessary to run +`php artisan native:install --force`, which completely rebuilds this directory, deleting all files within. + +For this reason, we also recommend you add the `nativephp` folder to your `.gitignore`. + +## Start your app + +**Heads up!** Before starting your app in a native context, try running it in the browser. You may bump into exceptions +which need addressing before you can run your app natively, and may be trickier to spot when doing so. + +Once you're ready: + +```shell +php artisan native:run +``` + +Just follow the prompts! This will start compiling your application and boot it on whichever device you select. + +### Running on a real device + +#### On iOS +If you want to run your app on a real iOS device, you need to make sure it is in +[Developer Mode](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device) +and that it's been added to your Apple Developer account as +[a registered device](https://developer.apple.com/account/resources/devices/list). + +#### On Android +On Android you need to [enable developer options](https://developer.android.com/studio/debug/dev-options#enable) +and have USB debugging (ADB) enabled. + +And that's it! You should now see your Laravel application running as a native app! πŸŽ‰ diff --git a/resources/views/docs/mobile/2/getting-started/introduction.md b/resources/views/docs/mobile/2/getting-started/introduction.md new file mode 100644 index 00000000..26506d7f --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/introduction.md @@ -0,0 +1,74 @@ +--- +title: Introduction +order: 1 +--- + +## Welcome to the revolution! + +NativePHP for Mobile is the first library of its kind that lets you run full PHP applications natively on mobile +devices β€” no web server required. + +By embedding a statically compiled PHP runtime alongside Laravel, and bridging directly into each platform’s native +APIs, NativePHP brings the power of modern PHP to truly native mobile apps. Build performant, offline-capable +experiences using the tools you already know. + +**It's never been this easy to build beautiful, local-first apps for iOS and Android.** + +## What makes NativePHP for Mobile special? + +- πŸ“± **Native performance** + Your app runs natively through an embedded PHP runtime optimized for each platform. +- πŸ”₯ **True mobile APIs** + Access camera, biometrics, push notifications, and more. One cohesive library that does it all. +- ⚑ **Laravel powered** + Leverage the entire Laravel ecosystem and your existing skillset. +- 🚫 **No web server required** + Your app runs entirely on-device and can operate completely offline-first. +- πŸ”„ **Cross platform** + Build apps for both iOS and Android from a single codebase. + +## Old tools, new tricks + +With NativePHP for Mobile, you don’t need to learn Swift, Kotlin, or anything new. +No new languages. No unfamiliar build tools. No fighting with Gradle or Xcode. + +Just PHP. + +Developers around the world are using the skills they already have to build and ship real mobile apps β€” faster than +ever. In just a few hours, you can go from code to app store submission. + +## How does it work? + +On the simplest level: + +1. A statically-compiled version of PHP is bundled with your code into a Swift/Kotlin shell application. +2. NativePHP's custom Swift/Kotlin bridges manage the PHP environment, running your PHP code directly. +3. A custom PHP extension is compiled into PHP, that exposes PHP interfaces to native functions. +4. Your app renders in a native web view, so you can continue developing your UI the way you're used to. + +You simply interact with an easy-to-use set of functions from PHP and everything just works! + +## Batteries included + +NativePHP for Mobile is way more than just a web view wrapper for your server-based application. Your application lives +_on device_ and is shipped with each installation. + +Thanks to our custom PHP extension, you can interact with many native APIs today, with more coming all the time, +including: + +- πŸ“· Camera & Gallery access +- πŸ” Biometric authentication (Face ID, Touch ID, Fingerprint) +- πŸ”” Push notifications via APNs (for iOS) or Firebase (both) +- πŸ’¬ Native dialogs & toasts +- πŸ”— Deep links & universal links +- πŸ“³ Haptic feedback & vibration +- πŸ”¦ Flashlight control +- πŸ“€ Native sharing +- πŸ”’ Secure storage (Keychain/Keystore) +- πŸ“ Location services + +You have the full power of PHP and Laravel at your fingertips... literally! And you're not sandboxed into the web view; +this goes way beyond what's possible with PWAs and WASM without any of the complexity... we've got full-cream PHP at +the ready! + +**What are you waiting for!? [Let's go!](quick-start)** diff --git a/resources/views/docs/mobile/2/getting-started/quick-start.md b/resources/views/docs/mobile/2/getting-started/quick-start.md new file mode 100644 index 00000000..b1936b88 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/quick-start.md @@ -0,0 +1,56 @@ +--- +title: Quick Start +order: 2 +--- + +## Let's go! + + + +If you've already got your [environment set up](environment-setup) to build mobile apps using Xcode and/or Android +Studio, then you can get building your first mobile app with NativePHP in minutes: + +### 1. Update your `composer.json` +Add the NativePHP Composer repository: + +```json +"repositories": [ + { + "type": "composer", + "url": "https://nativephp.composer.sh" + } +] +``` + +### 2. Set your app's identifier +You must set a `NATIVEPHP_APP_ID` in your `.env` file: + +```dotenv +NATIVEPHP_APP_ID=com.cocacola.cokezero +``` + +### 3. Install & run + +```bash +# Install NativePHP for Mobile into a new Laravel app +composer require nativephp/mobile + +# Ready your app to go native +php artisan native:install + +# Run your app on a mobile device +php artisan native:run +``` + +## Need help? + +- **Community** - Join our [Discord](/discord) for support and discussions. +- **Examples** - Check out the Kitchen Sink demo app + on [Android](https://play.google.com/store/apps/details?id=com.nativephp.kitchensinkapp) and + [iOS](https://testflight.apple.com/join/vm9Qtshy)! diff --git a/resources/views/docs/mobile/2/getting-started/roadmap.md b/resources/views/docs/mobile/2/getting-started/roadmap.md new file mode 100644 index 00000000..d54eeaf6 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/roadmap.md @@ -0,0 +1,45 @@ +--- +title: Roadmap +order: 400 +--- + +NativePHP for Mobile is stable and already deployed in production apps released on the app stores. But it's still early +days. We haven't yet built interfaces to all of the available mobile APIs. + +We're working on adding more and more features, including (in no particular order): + - Microphone access + - Bluetooth + - SMS (Android only) + - File picker + - Video camera access + - Document scanner + - Background tasks + - Geofencing + - Calendar access + - Local notifications, scheduled notifications + - Clipboard API + - Contacts access + - App badges + - OTA Updates + - App review prompt + - Proximity sensor + - Gyroscope + - Accelerometer + - Screen brightness + - More Haptic feedback + - Network info access + - Battery status + - CPU/Device information + - Ads + - In-app billing + + diff --git a/resources/views/docs/mobile/2/getting-started/support-policy.md b/resources/views/docs/mobile/2/getting-started/support-policy.md new file mode 100644 index 00000000..396f4fc6 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/support-policy.md @@ -0,0 +1,22 @@ +--- +title: Support Policy +order: 600 +--- + +NativePHP for Mobile is still very new. We aim to make it workable with as many versions of iOS and Android as is +reasonable. Considering that we have a very small team and a lot of work, our current stance on version support is this: + +**We aim (but do not guarantee) to support all the current and upcoming major, currently vendor-supported versions of +the platforms, with a focus on the current major release as a priority.** + +In practical terms, as of September 2025, this means we intend for NativePHP to be compatible β€” in part or in whole β€” +with: + +- iOS 18+ +- Android 13+ + +We do not guarantee support of all features across these versions, and whilst NativePHP may work in part on even older +versions than the currently-supported ones, we do not provide support for these under this standard policy. + +If you require explicit backwards compatibility with older or unsupported versions, we will be happy to have you join +our [partner](/partners) program, where a custom support policy can be arranged. diff --git a/resources/views/docs/mobile/2/getting-started/versioning.md b/resources/views/docs/mobile/2/getting-started/versioning.md new file mode 100644 index 00000000..192b5787 --- /dev/null +++ b/resources/views/docs/mobile/2/getting-started/versioning.md @@ -0,0 +1,69 @@ +--- +title: Versioning Policy +order: 500 +--- + +NativePHP for Mobile follows [semantic versioning](https://semver.org) with a mobile-specific approach that distinguishes between +Laravel-only changes and native code changes. This ensures predictable updates and optimal compatibility. + +Our aim is to limit the amount of work you need to do to get the latest updates and ensure everything works. + +We will aim to post update instructions with each release. + +## Release types + +### Patch releases + +Patch releases of `nativephp/mobile` should have **no breaking changes** and **only change Laravel/PHP code**. +This will typically include bug fixes and dependency updates that don't affect native code. + +These releases should be completely compatible with the existing version of your native applications. + +This means that you can: + +- Safely update via `composer update`. +- Avoid a complete rebuild (no need to `native:install --force`). +- Allow for easier app updates avoiding the app stores. + +### Minor releases + +Minor releases may contain **native code changes**. Respecting semantic versioning, these still should not contain +breaking changes, but there may be new native APIs, Kotlin/Swift updates, platform-specific features, or native +dependency changes. + +Minor releases will: + +- Require a complete rebuild (`php artisan native:install --force`) to work with the latest APIs. +- Need app store submission for distribution. +- Include advance notice and migration guides where necessary. + +### Major releases + +Major releases are reserved for breaking changes. This will usually follow a period of deprecations so that you have +time to make the necessary changes to your application code. + +## Version constraints + +We recommend using the [tilde range operator](https://getcomposer.org/doc/articles/versions.md#tilde-version-range-) +with a full minimum patch release defined in your `composer.json`: + +```json +{ + "require": { + "nativephp/mobile": "~1.1.0" + } +} +``` + +This automatically receives patch updates while giving you control over minor releases. + +## Your application versioning + +Just because we're using semantic versioning for the `nativephp/mobile` package, doesn't mean your app must follow that +same scheme. + +You have complete freedom in versioning your own applications! You may use semantic versioning, codenames, +date-based versions, or any scheme that works for your project, team or business. + +Remember that your app versions are usually public-facing (e.g. in store listings and on-device settings and update +screens) and can be useful for customers to reference if they need to contact you for help and support. diff --git a/resources/views/docs/mobile/2/the-basics/_index.md b/resources/views/docs/mobile/2/the-basics/_index.md new file mode 100644 index 00000000..373920fa --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/_index.md @@ -0,0 +1,4 @@ +--- +title: The Basics +order: 2 +--- \ No newline at end of file diff --git a/resources/views/docs/mobile/2/the-basics/app-icon.md b/resources/views/docs/mobile/2/the-basics/app-icon.md new file mode 100644 index 00000000..42d18f26 --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/app-icon.md @@ -0,0 +1,25 @@ +--- +title: App Icons +order: 300 +--- + +NativePHP makes it easy to apply a custom app icon to your iOS and Android apps. + +## Supply your icon + +Place a single high-resolution icon file at: `public/icon.png`. + +### Requirements +- Format: PNG +- Size: 1024 Γ— 1024 pixels +- Background: Transparent or solid β€” your choice +- GD PHP extension must be enabled, ensure it has enough memory (~2GB should be enough) + +This image will be automatically resized for all Android densities and used as the base iOS app icon. +You must have the GD extension installed in your development machine's PHP environment for this to work. + + diff --git a/resources/views/docs/mobile/2/the-basics/assets.md b/resources/views/docs/mobile/2/the-basics/assets.md new file mode 100644 index 00000000..a38f1f76 --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/assets.md @@ -0,0 +1,28 @@ +--- +title: Assets +order: 500 +--- + +## Compiling CSS and JavaScript + +If you are using React, Vue or another JavaScript library, or Tailwind CSS, tools that requires your frontend to be +built by build tooling like Vite, you will need to run your build process _before_ compiling the native application. + +For example, if you're using Vite with NPM to build a React application that is using Tailwind, to ensure that your +latest styles and JavaScript are included, always run `npm run build` before running `php artisan native:run`. + +## Other files + +NativePHP will include all files from the root of your Laravel application. So you can store any files that you wish to +make available to your application wherever makes the most sense for you. + + diff --git a/resources/views/docs/mobile/2/the-basics/edge.md b/resources/views/docs/mobile/2/the-basics/edge.md new file mode 100644 index 00000000..5f6a94d5 --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/edge.md @@ -0,0 +1,44 @@ +--- +title: EDGE Components +order: 150 +--- + +## What is EDGE? + +EDGE (Element Definition and Generation Engine) is NativePHP Mobile's component system that transforms Blade syntax into platform-native UI elements. + +Instead of rendering in the WebView, EDGE components are compiled into truly native navigation elements that match each platform's design guidelines - Material Design on Android and iOS native patterns on iOS. + +## Available Components + +EDGE provides navigation components for building native mobile interfaces: + +- **[Bottom Navigation](/docs/mobile/2/edge-components/bottom-nav)** - Bottom navigation bar with up to 5 items +- **[Top Bar](/docs/mobile/2/edge-components/top-bar)** - Top app bar with title and action buttons +- **[Floating Action Button](/docs/mobile/2/edge-components/fab)** - Floating button for primary actions +- **[Side Navigation](/docs/mobile/2/edge-components/side-nav)** - Slide-out navigation drawer + +## How It Works + +Write familiar Blade components in your layouts: + +@verbatim +```blade + + + +``` +@endverbatim + +EDGE processes these during the build and renders them as native components that sit outside your WebView, providing better performance and a truly native feel. + +## Notes + +- Components are rendered natively, not in the WebView +- Updates require a page reload or Livewire refresh +- Automatically adapt to platform design guidelines \ No newline at end of file diff --git a/resources/views/docs/mobile/2/the-basics/events.md b/resources/views/docs/mobile/2/the-basics/events.md new file mode 100644 index 00000000..07b7b7ae --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/events.md @@ -0,0 +1,112 @@ +--- +title: Events +order: 200 +--- + +## Overview + +Many native mobile operations take time to complete and await user interaction. PHP isn't really set up to handle this +sort of asynchronous behaviour; it is built to do its work, send a response and move on as quickly as possible. + +NativePHP for Mobile smooths over this disparity between the different paradigms using a simple event system that +handles completion of asynchronous methods using a webhook-/websocket-style approach to notify your Laravel app. + +## Understanding Async vs Sync + +Not all actions are async. Some methods run immediately, and in some cases return a result straight away. + +Here are a few of the **synchronous** APIs: + +```php +Haptics::vibrate(); +System::flashlight(); +Dialog::toast('Hello!'); +``` +Asynchronous actions trigger operations that may complete later. These return immediately, usually with a `bool` or +`void`, allowing PHP's execution to finish. In many of these cases, the user interacts directly with a native component. +When the user has completed their task and the native UI is dismissed, the native app + +```php +// These trigger operations and fire events when complete +Camera::getPhoto(); // β†’ PhotoTaken event +Biometrics::promptForBiometricID(); // β†’ Completed event +PushNotifications::enrollForPushNotifications(); // β†’ TokenGenerated event +``` + +## Basic Event Structure + +All events are standard [Laravel Event classes](https://laravel.com/docs/12.x/events#defining-events). The public +properties of the events contain the pertinent data coming from the native app side. + +## Event Handling + +All asynchronous methods follow the same pattern: + +1. **Call the method** to trigger the operation. +2. **Listen for the appropriate events** to handle the result. +3. **Update your UI** based on the outcome. + +All events get sent directly to JavaScript in the web view _and_ to your PHP application via a special route. This +allows you to listen for these events in the context that best suits your application. + +### On the frontend + +Events are 'broadcast' to the frontend of your application via the web view through a custom `Native` helper. You can +easily listen for these events in JavaScript in two ways: + +- The `Native.on()` helper +- Livewire's `#[On()]` attribute + +#### The `Native.on()` helper + +Register the event listener directly in JavaScript: + +```blade +@@use(Native\Mobile\Events\Alert\ButtonPressed) + + +``` + +#### Livewire's `#[On()]` attribute + +Livewire makes listening to 'broadcast' events simple. Just add the event name, prefixed by `native:` to the `#[On()]` +attribute attached to the method you want to use as its handler: + +```php +use Native\Mobile\Events\Camera\PhotoTaken; + +#[On('native:'.PhotoTaken::class)] +public function handlePhoto(string $path) +{ + // Handle captured photo +} +``` + +### On the backend + +You can also listen for these events on the PHP side as they are simultaneously passed to your Laravel application. + +Simply [add a listener](https://laravel.com/docs/12.x/events#registering-events-and-listeners) as you normally would: + +```php +use App\Services\APIService; +use Native\Mobile\Events\Camera\PhotoTaken; + +class UpdateAvatar +{ + public function __construct(private APIService $api) {} + + public function handle(PhotoTaken $event): void + { + $imageData = base64_encode( + file_get_contents($event->path) + ); + + $this->api->updateAvatar($imageData); + } +} +``` diff --git a/resources/views/docs/mobile/2/the-basics/native-functions.md b/resources/views/docs/mobile/2/the-basics/native-functions.md new file mode 100644 index 00000000..a6fc4666 --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/native-functions.md @@ -0,0 +1,33 @@ +--- +title: Native Functions +order: 100 +--- + +Our custom PHP extension enables tight integration with each platform, providing a consistent and performant abstraction +that lets you focus on building your app. Build for both platforms while you develop on one. + +Native device functions are called directly from your PHP code, giving you access to platform-specific features while +maintaining the productivity and familiarity of Laravel development. + +These functions are called from your PHP code using an ever-growing list of classes. These classes are also wrapped in +Laravel Facades for ease of access and testing: + +- `Native\Mobile\Facades\Biometrics` +- `Native\Mobile\Facades\Camera` +- `Native\Mobile\Facades\Dialog` +- `Native\Mobile\Facades\Geolocation` +- `Native\Mobile\Facades\Haptics` +- `Native\Mobile\Facades\NativeUI` +- `Native\Mobile\Facades\PushNotifications` +- `Native\Mobile\Facades\Scanner` +- `Native\Mobile\Facades\SecureStorage` +- `Native\Mobile\Facades\System` + + diff --git a/resources/views/docs/mobile/2/the-basics/overview.md b/resources/views/docs/mobile/2/the-basics/overview.md new file mode 100644 index 00000000..3ef606ce --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/overview.md @@ -0,0 +1,58 @@ +--- +title: Overview +order: 50 +--- + +NativePHP for Mobile is made up of multiple parts: + +- A Laravel application (PHP) +- The `nativephp/mobile` Composer package +- A custom build of PHP with custom NativePHP extension +- Native applications (Swift & Kotlin) + +## Your Laravel app + +You can build your Laravel application just as you normally would, for the most part, sprinkling native functionality +in where desired by using NativePHP's built-in APIs. + +## `nativephp/mobile` + +The package is a pretty normal Composer package. It contains the PHP code needed to interface with the NativePHP +extension, the tools to install and run your applications, and all the code for each native application - iOS and +Android. + +## The PHP builds + +When you run the `native:install` Artisan command, the package will fetch the appropriate versions of the custom-built +PHP binaries. + +NativePHP for Mobile currently bundles **PHP 8.4**. You should ensure that your application is built to work with this +version of PHP. + +These custom PHP builds have been compiled specifically to target the mobile platforms and cannot be used in other +contexts. + +They are compiled as embeddable C libraries and embedded _into_ the native application. In this way, PHP doesn't run as +a separate process/service under a typical web server environment; essentially, the native application itself is +extended with the capability to execute your PHP code. + +Your Laravel application is then executed directly by the native app, using the embedded PHP engine to run the code. +This runs PHP as close to natively as it can get. It is very fast and efficient on modern hardware. + +## The native apps + +NativePHP ships one app for iOS and one for Android. When you run the `native:run` Artisan command, your Laravel app is +packaged up and copied into one of these apps. + +To build for both platforms, you must run the `native:run` command twice, targeting each platform. + +Each native app "shell" runs a number of steps to prepare the environment each time your application is booted, +including: + +- Checking to see if the bundled version of your Laravel app is newer than the installed version + - Installing the newer version if necessary +- Running migrations +- Clearing caches + +Normally, this process takes just a couple of seconds in normal use. After your app has been updated, it will take a +few seconds longer. diff --git a/resources/views/docs/mobile/2/the-basics/splash-screens.md b/resources/views/docs/mobile/2/the-basics/splash-screens.md new file mode 100644 index 00000000..1c803e4e --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/splash-screens.md @@ -0,0 +1,18 @@ +--- +title: Splash Screens +order: 400 +--- + +NativePHP makes it easy to add custom splash screens to your iOS and Android apps. + +## Supply your Splash Screens + +Place the relevant files in the locations specified: + +- `public/splash.png` - for the Light Mode splash screen +- `public/splash-dark.png` - for the Dark Mode splash screen + +### Requirements +- Format: PNG +- Minimum Size/Ratio: 1080 Γ— 1920 pixels +- GD PHP extension must be enabled, ensure it has enough memory (~2GB should be enough) diff --git a/resources/views/docs/mobile/2/the-basics/web-view.md b/resources/views/docs/mobile/2/the-basics/web-view.md new file mode 100644 index 00000000..d201b8d2 --- /dev/null +++ b/resources/views/docs/mobile/2/the-basics/web-view.md @@ -0,0 +1,132 @@ +--- +title: Web View +order: 60 +--- + +Every mobile app built with NativePHP centers around a single native web view. The web view allows you to use whichever +web technologies you are most comfortable with to build your app's user interface (UI). + +You're not limited to any one tool or framework β€” you can use Livewire, Vue, React, Svelte, HTMX... even jQuery! +Whatever you're most comfortable with for building a web UI, you can use to build a mobile app with NativePHP. + +The web view is rendered to fill the entire view of your application and is intended to remain visible to your users at +all times β€” except when another full-screen action takes place, such as accessing the camera or an in-app browser. + +## The Viewport + +Just like a normal browser, the web view has the concept of a **viewport** which represents the viewable area of the +page. The viewport can be controlled with the `viewport` meta tag, just as you would in a traditional web application: + +```html + +``` + +### Disable Zoom +When building mobile apps, you may want to have a little more control over the experience. For example, you may +want to disable user-controlled zoom, allowing your app to behave similarly to a traditional native app. + +To achieve this, you can set `user-scalable=no`: + +```html + +``` + +## Edge-to-Edge + +To give you the most flexibility in how you design your app's UI, the web view occupies the entire screen, allowing you +to render anything anywhere on the display whilst your app is in the foreground using just HTML, CSS and JavaScript. + +But you should bear in mind that not all parts of the display are visible to the user. Many devices have camera +notches, rounded corners and curved displays. These areas may still be considered part of the `viewport`, but they may +be invisible and/or non-interactive. + +To account for this in your UI, you should set the `viewport-fit=cover` option in your `viewport` meta tag and use the +safe area insets. + +### Safe Areas + +Safe areas are the sections of the display which are not obscured by either a physical interruption (a rounded corner +or camera), or some persistent UI, such as the Home Indicator (a.k.a. the bottom bar) or notch. + +Safe areas are calculated for your app by the device at runtime and adjust according to its orientation, allowing your +UI to be responsive to the various device configurations with a simple and predictable set of CSS rules. + +The fundamental building blocks are a set of four values known as `insets`. These are injected into your pages as the +following CSS variables: + +- `--inset-top` +- `--inset-bottom` +- `--inset-left` +- `--inset-right` + +You can apply these insets in whichever way you need to build a usable interface. + +There is also a handy `nativephp-safe-area` CSS class that can be applied to most elements to ensure they sit within +the safe areas of the display. + +Say you want a `fixed`-position header bar like this: + +![](/img/docs/viewport-fit-cover.png) + +If you're using Tailwind, you might try something like this: + +```html +
+ ... +
+``` + +If you tried to do this without `viewport-fit=cover` and use of the safe areas, here's what you'd end up with in +portrait view: + +![](/img/docs/viewport-default.png) + +And it may be even worse in landscape view: + +![](/img/docs/viewport-default-landscape.png) + +But by adding a few simple adjustments to our page, we can make it beautiful again (Well, maybe we should lose the +red...): + +```html + +
+ ... +
+``` + +![](/img/docs/viewport-fit-cover-landscape.png) + +### Status Bar Style + +On Android, the icons in the Status Bar do not change color automatically based on the background color in your app. +By default, they change based on whether the device is in Light/Dark Mode. + +If you have a consistent background color in both light and dark mode, you may use the `nativephp.status_bar_style` +config key to set the appropriate status bar style for your app to give users the best experience. + +The possible options are: + +- `auto` - the default, which changes based on the device's Dark Mode setting +- `light` - ideal if your app's background is dark-colored +- `dark` - better if your app's background is light-colored + + + +With just a few small changes, we've been able to define a layout that will work well on a multitude of devices +without having to add complex calculations or lots of device-specific CSS rules to our code.