From 2cc0fe559fabe173c2d4f0270b260e9878d2bcd6 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 13 Jul 2025 03:22:25 +0100 Subject: [PATCH] polish --- resources/views/docs/mobile/1/_index.md | 95 ----- .../views/docs/mobile/1/apis/biometrics.md | 50 +-- resources/views/docs/mobile/1/apis/browser.md | 13 +- resources/views/docs/mobile/1/apis/camera.md | 75 +--- resources/views/docs/mobile/1/apis/dialog.md | 47 +-- .../views/docs/mobile/1/apis/geolocation.md | 104 +---- resources/views/docs/mobile/1/apis/haptics.md | 55 +-- .../views/docs/mobile/1/apis/overview.md | 95 ----- .../docs/mobile/1/apis/push-notifications.md | 111 +----- .../docs/mobile/1/apis/secure-storage.md | 27 +- resources/views/docs/mobile/1/apis/system.md | 33 +- .../views/docs/mobile/1/concepts/ci-cd.md | 14 +- .../views/docs/mobile/1/concepts/databases.md | 109 +++--- .../docs/mobile/1/concepts/deep-links.md | 259 +++---------- .../mobile/1/concepts/push-notifications.md | 282 +++----------- .../mobile/1/concepts/splash-screen-icons.md | 359 ------------------ .../mobile/1/getting-started/configuration.md | 83 +++- .../mobile/1/getting-started/development.md | 112 +++++- .../1/getting-started/environment-setup.md | 74 +++- .../mobile/1/getting-started/installation.md | 116 +++--- .../mobile/1/getting-started/introduction.md | 37 +- .../mobile/1/getting-started/quick-start.md | 35 ++ .../docs/mobile/1/getting-started/roadmap.md | 36 +- .../mobile/1/getting-started/versioning.md | 71 ++-- .../docs/mobile/1/the-basics/app-assets.md | 51 --- .../docs/mobile/1/the-basics/app-icon.md | 24 ++ .../views/docs/mobile/1/the-basics/assets.md | 28 ++ .../1/the-basics/asynchronous-methods.md | 308 --------------- .../views/docs/mobile/1/the-basics/events.md | 112 ++++++ .../docs/mobile/1/the-basics/icu-support.md | 60 --- .../mobile/1/the-basics/native-functions.md | 18 +- .../docs/mobile/1/the-basics/overview.md | 58 +++ .../mobile/1/the-basics/splash-screens.md | 17 + 33 files changed, 873 insertions(+), 2095 deletions(-) delete mode 100644 resources/views/docs/mobile/1/apis/overview.md delete mode 100644 resources/views/docs/mobile/1/concepts/splash-screen-icons.md create mode 100644 resources/views/docs/mobile/1/getting-started/quick-start.md delete mode 100644 resources/views/docs/mobile/1/the-basics/app-assets.md create mode 100644 resources/views/docs/mobile/1/the-basics/app-icon.md create mode 100644 resources/views/docs/mobile/1/the-basics/assets.md delete mode 100644 resources/views/docs/mobile/1/the-basics/asynchronous-methods.md create mode 100644 resources/views/docs/mobile/1/the-basics/events.md delete mode 100644 resources/views/docs/mobile/1/the-basics/icu-support.md create mode 100644 resources/views/docs/mobile/1/the-basics/overview.md create mode 100644 resources/views/docs/mobile/1/the-basics/splash-screens.md diff --git a/resources/views/docs/mobile/1/_index.md b/resources/views/docs/mobile/1/_index.md index 68ac888e..c719fbe2 100644 --- a/resources/views/docs/mobile/1/_index.md +++ b/resources/views/docs/mobile/1/_index.md @@ -2,98 +2,3 @@ title: Mobile order: 1 --- - -# NativePHP for Mobile - -**Build native iOS and Android apps with PHP and Laravel** - -NativePHP for Mobile revolutionizes mobile development by allowing PHP developers to create native mobile applications using the languages and frameworks they already know and love. No need to learn Swift, Kotlin, or React Native - just pure PHP and Laravel. - -## What Makes NativePHP Mobile Special? - -πŸ“±**Native Performance** - Your app runs natively on device with embedded PHP runtime -πŸ”₯**True Mobile APIs** - Access camera, biometrics, push notifications, and more -⚑ **Laravel Powered** - Use your existing Laravel skills and ecosystem -🚫**No Web Server** - Your app runs entirely on-device -πŸ”„**Cross Platform** - Single codebase for iOS and Android - -## Quick Start - -Get your first mobile app running in minutes: - -```bash -# Install NativePHP Mobile -composer require nativephp/mobile - -# Configure your app -php artisan native:install - -# Run your app -php artisan native:run -``` - -## Current Features (v1.1) - -**Available now:** -- πŸ“· Camera & Gallery access -- πŸ” Biometric authentication (Face ID, Touch ID, Fingerprint) -- πŸ”” Push notifications via Firebase -- πŸ’¬ Native dialogs & toasts -- πŸ”— Deep links & universal links -- πŸ“± NFC support -- πŸ“³ Haptic feedback & vibration -- πŸ”¦ Flashlight control -- πŸ“€ Native sharing -- πŸ”’ Secure storage (Keychain/Keystore) -- πŸ“ Location services - -[See the complete roadmap πŸ—ΊοΈ](/docs/mobile/1/getting-started/roadmap) - -## Documentation Sections - -### [Getting Started](/docs/mobile/1/getting-started) -Everything you need to start building mobile apps with PHP: -- [Introduction](/docs/mobile/1/getting-started/introduction) - Learn how NativePHP Mobile works -- [Installation](/docs/mobile/1/getting-started/installation) - Set up your development environment -- [Environment Setup](/docs/mobile/1/getting-started/environment-setup) - Configure iOS and Android tools -- [Configuration](/docs/mobile/1/getting-started/configuration) - App settings and permissions -- [Development](/docs/mobile/1/getting-started/development) - Development workflow -- [Roadmap](/docs/mobile/1/getting-started/roadmap) - Current and planned features - -### [The Basics](/docs/mobile/1/the-basics) -Core concepts and fundamental knowledge: -- [Native Functions](/docs/mobile/1/the-basics/native-functions) - Understanding sync vs async APIs -- [Asynchronous Methods](/docs/mobile/1/the-basics/asynchronous-methods) - Event-driven mobile development -- [ICU Support](/docs/mobile/1/the-basics/icu-support) - International components for Unicode - -### [Concepts](/docs/mobile/1/concepts) -Important concepts for mobile app development: -- [CI/CD](/docs/mobile/1/concepts/ci-cd) - Continuous integration and deployment -- [Deep Links](/docs/mobile/1/concepts/deep-links) - Universal links, app links, and NFC -- [Push Notifications](/docs/mobile/1/concepts/push-notifications) - Firebase Cloud Messaging setup -- [Splash Screen/Icons](/docs/mobile/1/concepts/splash-screen-icons) - App branding and assets -- [Versioning](/docs/mobile/1/concepts/versioning) - App version management - -### [APIs](/docs/mobile/1/apis) -Complete API reference for all native features: -- [Biometrics](/docs/mobile/1/apis/biometrics) - Face ID, Touch ID, fingerprint authentication -- [Camera](/docs/mobile/1/apis/camera) - Photo capture and gallery access -- [Dialog](/docs/mobile/1/apis/dialog) - Alerts, toasts, and sharing -- [Geolocation](/docs/mobile/1/apis/geolocation) - GPS and location services -- [Haptics](/docs/mobile/1/apis/haptics) - Vibration and tactile feedback -- [PushNotifications](/docs/mobile/1/apis/push-notifications) - FCM token management -- [SecureStorage](/docs/mobile/1/apis/secure-storage) - Keychain and keystore operations -- [System](/docs/mobile/1/apis/system) - Flashlight and legacy methods - -### [Digging Deeper](/docs/mobile/1/digging-deeper) -Advanced topics for production apps: -- [Databases](/docs/mobile/1/digging-deeper/databases) - SQLite and data management -- [Security](/docs/mobile/1/digging-deeper/security) - Best practices and secure storage - -## Need Help? - -- **License Required** - [Purchase your license](https://nativephp.com/mobile) to get started -- **Community** - Join our Discord for support and discussions -- **Examples** - Check out the Kitchen Sink demo app (coming soon to app stores) - -Ready to build your first mobile app with PHP? [Let's get started! πŸš€](/docs/mobile/1/getting-started/introduction) diff --git a/resources/views/docs/mobile/1/apis/biometrics.md b/resources/views/docs/mobile/1/apis/biometrics.md index e3f4ed2e..1a6bff46 100644 --- a/resources/views/docs/mobile/1/apis/biometrics.md +++ b/resources/views/docs/mobile/1/apis/biometrics.md @@ -5,7 +5,8 @@ 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. +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; @@ -17,6 +18,12 @@ use Native\Mobile\Facades\Biometrics; Prompts the user for biometric authentication. +```php +use Native\Mobile\Facades\Biometrics; + +Biometrics::promptForBiometricID(); +``` + ## Events ### `Completed` @@ -27,7 +34,7 @@ Fired when biometric authentication completes (success or failure). use Livewire\Attributes\On; use Native\Mobile\Events\Biometric\Completed; -#[On('native:' . Completed::class)] +#[On('native:'.Completed::class)] public function handleBiometricAuth(bool $success) { if ($success) { @@ -40,45 +47,6 @@ public function handleBiometricAuth(bool $success) } ``` -## Example Usage - -```php -use Livewire\Component; -use Livewire\Attributes\On; -use Native\Mobile\Facades\Biometrics; -use Native\Mobile\Events\Biometric\Completed; - -class SecureArea extends Component -{ - public bool $isUnlocked = false; - public bool $isAuthenticating = false; - - public function authenticate() - { - $this->isAuthenticating = true; - Biometrics::promptForBiometricID(); - } - - #[On('native:' . Completed::class)] - public function handleBiometricAuth(bool $success) - { - $this->isAuthenticating = false; - - if ($success) { - $this->isUnlocked = true; - session(['biometric_authenticated' => true]); - } else { - $this->addError('auth', 'Biometric authentication failed'); - } - } - - public function render() - { - return view('livewire.secure-area'); - } -} -``` - ## Platform Support - **iOS:** Face ID, Touch ID diff --git a/resources/views/docs/mobile/1/apis/browser.md b/resources/views/docs/mobile/1/apis/browser.md index 5910bf03..5e51061a 100644 --- a/resources/views/docs/mobile/1/apis/browser.md +++ b/resources/views/docs/mobile/1/apis/browser.md @@ -1,11 +1,12 @@ --- title: Browser -order: 250 +order: 150 --- ## Overview -The Browser API provides three methods for opening URLs in mobile apps, each designed for specific use cases: in-app browsing, system browser navigation, and OAuth authentication flows. +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; @@ -55,11 +56,3 @@ Browser::auth('https://provider.com/oauth/authorize?client_id=123&redirect_uri=n - Login with WorkOS, Auth0, Google, Facebook, etc. - Secure authentication with automatic redirects - Isolated browser session for security - -## Platform Behavior - -- **iOS**: Uses SFSafariViewController (inApp), Safari (system), ASWebAuthenticationSession (auth) -- **Android**: Uses Custom Tabs (inApp), default browser (system), Custom Tabs with auth handling (auth) - -The Browser API provides the right tool for each browsing scenario in your mobile application. - diff --git a/resources/views/docs/mobile/1/apis/camera.md b/resources/views/docs/mobile/1/apis/camera.md index da2f750c..24841f0d 100644 --- a/resources/views/docs/mobile/1/apis/camera.md +++ b/resources/views/docs/mobile/1/apis/camera.md @@ -54,7 +54,7 @@ Fired when a photo is taken with the camera. use Livewire\Attributes\On; use Native\Mobile\Events\Camera\PhotoTaken; -#[On('native:' . PhotoTaken::class)] +#[On('native:'.PhotoTaken::class)] public function handlePhotoTaken(string $path) { // Process the captured photo @@ -72,7 +72,7 @@ Fired when media is selected from the gallery. use Livewire\Attributes\On; use Native\Mobile\Events\Gallery\MediaSelected; -#[On('native:' . MediaSelected::class)] +#[On('native:'.MediaSelected::class)] public function handleMediaSelected($success, $files, $count) { foreach ($files as $file) { @@ -82,80 +82,9 @@ public function handleMediaSelected($success, $files, $count) } ``` -## Example Usage - -```php -use Livewire\Component; -use Livewire\Attributes\On; -use Native\Mobile\Facades\Camera; -use Native\Mobile\Events\Camera\PhotoTaken; -use Native\Mobile\Events\Gallery\MediaSelected; - -class PhotoManager extends Component -{ - public array $photos = []; - public bool $isCapturing = false; - - public function takePhoto() - { - $this->isCapturing = true; - Camera::getPhoto(); - } - - public function pickFromGallery() - { - Camera::pickImages('images', true, 5); - } - - #[On('native:' . PhotoTaken::class)] - public function handlePhotoTaken(string $path) - { - $this->isCapturing = false; - $this->addPhoto($path); - } - - #[On('native:' . MediaSelected::class)] - public function handleMediaSelected($success, $files, $count) - { - foreach ($files as $file) { - $this->addPhoto($file); - } - } - - private function addPhoto(string $path) - { - $this->photos[] = [ - 'path' => $path, - 'data_url' => $this->createDataUrl($path), - 'timestamp' => now() - ]; - } - - private function createDataUrl(string $path): string - { - $data = base64_encode(file_get_contents($path)); - $mime = mime_content_type($path); - return "data:$mime;base64,$data"; - } - - public function render() - { - return view('livewire.photo-manager'); - } -} -``` - -## Platform Support - -- **iOS:** Uses UIImagePickerController and Photos framework -- **Android:** Uses `Intent.ACTION_IMAGE_CAPTURE` and gallery intents -- **Permissions:** Camera permission required for photo capture -- **File Location:** Photos saved to app's temporary directory - ## 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 -- Consider implementing cleanup for old temporary photos - File formats are platform-dependent (typically JPEG) diff --git a/resources/views/docs/mobile/1/apis/dialog.md b/resources/views/docs/mobile/1/apis/dialog.md index e66dc529..ad7bc558 100644 --- a/resources/views/docs/mobile/1/apis/dialog.md +++ b/resources/views/docs/mobile/1/apis/dialog.md @@ -39,6 +39,7 @@ Dialog::alert( Displays a brief toast notification message. + **Parameters:** - `string $message` - The message to display @@ -46,6 +47,13 @@ Displays a brief toast notification message. 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. @@ -77,7 +85,7 @@ Fired when a button is pressed in an alert dialog. use Livewire\Attributes\On; use Native\Mobile\Events\Alert\ButtonPressed; -#[On('native:' . ButtonPressed::class)] +#[On('native:'.ButtonPressed::class)] public function handleAlertButton($index, $label) { switch ($index) { @@ -93,40 +101,3 @@ public function handleAlertButton($index, $label) } } ``` - -## Toast Guidelines - -### Best Practices -- Keep messages short and clear -- Use for confirmations and status updates -- Don't rely on toasts for critical information -- Avoid showing multiple toasts in quick succession - -```php -// Good toast messages -Dialog::toast('Saved!'); -Dialog::toast('Photo uploaded'); -Dialog::toast('Settings updated'); - -// Avoid long messages -Dialog::toast('Your photo has been successfully uploaded to the server and will be processed shortly'); -``` - -## Platform Differences - -### iOS -- Alerts use UIAlertController -- Toasts use custom overlay views -- Sharing uses UIActivityViewController - -### Android -- Alerts use AlertDialog -- Toasts use native Toast system -- Sharing uses Intent.ACTION_SEND - -## Accessibility - -- All dialogs automatically support screen readers -- Button text should be descriptive -- Toast messages are announced by accessibility services -- Consider users with motor disabilities when designing button layouts diff --git a/resources/views/docs/mobile/1/apis/geolocation.md b/resources/views/docs/mobile/1/apis/geolocation.md index 4ca4bad9..0a2e4f84 100644 --- a/resources/views/docs/mobile/1/apis/geolocation.md +++ b/resources/views/docs/mobile/1/apis/geolocation.md @@ -69,27 +69,17 @@ Fired when location data is requested (success or failure). 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) -{ - if ($success) { - // Location successfully retrieved - $this->latitude = $latitude; - $this->longitude = $longitude; - $this->accuracy = $accuracy; - $this->provider = $provider; - - Log::info('Location received', [ - 'lat' => $latitude, - 'lng' => $longitude, - 'accuracy' => $accuracy, - 'provider' => $provider - ]); - } else { - // Location request failed - $this->error = $error ?? 'Failed to get location'; - Log::warning('Location request failed', ['error' => $error]); - } +#[On('native:'.LocationReceived::class)] +public function handleLocationReceived( + $success = null, + $latitude = null, + $longitude = null, + $accuracy = null, + $timestamp = null, + $provider = null, + $error = null +) { + // ... } ``` @@ -111,20 +101,10 @@ Fired when permission status is checked. use Livewire\Attributes\On; use Native\Mobile\Events\Geolocation\PermissionStatusReceived; -#[On('native:' . PermissionStatusReceived::class)] +#[On('native:'.PermissionStatusReceived::class)] public function handlePermissionStatus($location, $coarseLocation, $fineLocation) { - $this->locationPermission = $location; - $this->coarsePermission = $coarseLocation; - $this->finePermission = $fineLocation; - - if ($coarseLocation === 'granted' || $fineLocation === 'granted') { - // At least some location permission is granted - $this->canRequestLocation = true; - } else { - // No location permissions granted - $this->showPermissionExplanation(); - } + // ... } ``` @@ -150,82 +130,26 @@ use Native\Mobile\Events\Geolocation\PermissionRequestResult; public function handlePermissionRequest($location, $coarseLocation, $fineLocation, $message = null, $needsSettings = null) { if ($location === 'permanently_denied') { - // Permission permanently denied - must go to Settings - $this->error = $message ?? 'Location permission permanently denied. Please enable in Settings.'; - $this->showSettingsPrompt = true; + $this->error = 'Location permission permanently denied. Please enable in Settings.'; } elseif ($coarseLocation === 'granted' || $fineLocation === 'granted') { - // Permission granted - can now request location - $this->permissionGranted = true; $this->getCurrentLocation(); } else { - // Permission denied but can ask again $this->error = 'Location permission is required for this feature.'; } } ``` -## Understanding Permission States - -### Permission Types - -**Coarse Location (`ACCESS_COARSE_LOCATION` on Android)** -- Network-based location (WiFi, cellular towers) -- Lower accuracy (~100-1000 meters) -- Less battery usage -- Faster location fixes - -**Fine Location (`ACCESS_FINE_LOCATION` on Android, Location Services on iOS)** -- GPS-based location -- Higher accuracy (~5-50 meters) -- More battery usage -- Slower initial location fix - - -## Platform Support - -### iOS -- Uses Core Location framework -- Requires location usage description in Info.plist -- Supports both "When in Use" and "Always" permissions -- Automatic permission prompts - -### Android -- Uses FusedLocationProviderClient (Google Play Services) -- Requires location permissions in AndroidManifest.xml -- Supports coarse and fine location permissions -- Runtime permission requests (Android 6+) - ## Privacy Considerations -### Best Practices - **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 -## Accuracy and Performance - -### Choosing Accuracy Level - -```php -// For general location (city-level) -Geolocation::getCurrentPosition(false); // ~100-1000m accuracy - -// For precise location (navigation, delivery) -Geolocation::getCurrentPosition(true); // ~5-50m accuracy -``` - ### 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 -### Error Handling -- Always handle both success and failure cases -- Provide meaningful error messages to users -- Implement fallback strategies (manual entry, saved locations) -- Log errors for debugging but don't expose sensitive details - -The Geolocation API provides powerful location capabilities while respecting user privacy and platform requirements. Always handle permissions gracefully and provide clear value propositions for why location access is needed. diff --git a/resources/views/docs/mobile/1/apis/haptics.md b/resources/views/docs/mobile/1/apis/haptics.md index 6cc1e290..2ec5c28b 100644 --- a/resources/views/docs/mobile/1/apis/haptics.md +++ b/resources/views/docs/mobile/1/apis/haptics.md @@ -23,58 +23,7 @@ Triggers device vibration for tactile feedback. Haptics::vibrate(); ``` -## Example Usage +**Use haptics for:** Button presses, form validation, important notifications, game events. -### Basic Form Feedback -```php -use Livewire\Component; -use Native\Mobile\Facades\Haptics; - -class FormComponent extends Component -{ - public function save() - { - if ($this->hasErrors()) { - // Haptic feedback for errors - Haptics::vibrate(); - return; - } - - $this->saveData(); - - // Success haptic feedback - Haptics::vibrate(); - } - - public function deleteItem() - { - // Haptic feedback for important actions - Haptics::vibrate(); - $this->performDelete(); - } -} -``` - -### Best Practices -```php -class HapticsExample extends Component -{ - // βœ… Good: Button presses, form errors, important actions - public function onButtonPress() - { - Haptics::vibrate(); - $this->processAction(); - } - - // ❌ Avoid: Frequent events like scrolling - public function onScroll() - { - // Don't vibrate on every scroll - too annoying! - // Haptics::vibrate(); - } -} -``` - -**Use haptics for:** Button presses, form validation, important notifications, game events -**Avoid haptics for:** Frequent events, background processes, minor updates +**Avoid haptics for:** Frequent events, background processes, minor updates. diff --git a/resources/views/docs/mobile/1/apis/overview.md b/resources/views/docs/mobile/1/apis/overview.md deleted file mode 100644 index 87cce521..00000000 --- a/resources/views/docs/mobile/1/apis/overview.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Overview -order: 1 ---- -# API Reference - -Complete documentation for all NativePHP Mobile APIs. Each API provides access to native device capabilities through familiar PHP facades. - -## Available APIs - -### Biometrics -**Face ID, Touch ID, Fingerprint Authentication** -```php -Biometrics::promptForBiometricID(); -``` -Secure user authentication using device biometric sensors. Supports Face ID on iOS, Touch ID, and fingerprint readers on Android. - -### Camera -**Photo Capture & Gallery Access** -```php -Camera::getPhoto(); -Camera::pickImages('images', true, 5); -``` -Take photos with the device camera or select images from the photo gallery. Supports both single and multiple image selection. - -### Dialog -**Native UI Elements** -```php -Dialog::alert('Title', 'Message', $buttons, $callback); -Dialog::toast('Success message'); -Dialog::share('Title', 'Text', 'https://example.com'); -``` -Display native alerts, toast notifications, and sharing interfaces that match platform design guidelines. - -### Geolocation -**GPS & Location Services** -```php -Geolocation::getCurrentPosition(true); // High accuracy -Geolocation::checkPermissions(); -Geolocation::requestPermissions(); -``` -Access device location services with configurable accuracy levels and proper permission handling. - -### Haptics -**Vibration & Tactile Feedback** -```php -Haptics::vibrate(); -``` -Provide tactile feedback for user interactions, form validation, and important events. - -### PushNotifications -**Firebase Cloud Messaging** -```php -PushNotifications::enrollForPushNotifications(); -PushNotifications::getPushNotificationsToken(); -``` -Register devices for push notifications and manage FCM tokens for server-side notification delivery. - -### SecureStorage -**Keychain & Keystore Operations** -```php -SecureStorage::set('api_token', $token); -$token = SecureStorage::get('api_token'); -SecureStorage::delete('api_token'); -``` -Store sensitive data securely using iOS Keychain and Android Keystore with automatic encryption. - -### System -**System Functions & Legacy API** -```php -System::flashlight(); // Toggle flashlight -``` -Control system functions like the flashlight. Also provides deprecated methods that have moved to dedicated facades. - -## API Patterns - -### Synchronous APIs -Execute immediately and return results: -- `Haptics::vibrate()` -- `System::flashlight()` -- `Dialog::toast()` -- `SecureStorage::set()` / `get()` - -### Asynchronous APIs -[Read more about asynchronous API methods here.](/docs/mobile/1/the-basics/asynchronous-methods) - -## Platform Support - -All APIs work on both iOS and Android with platform-appropriate implementations: -- **iOS**: Uses native iOS frameworks and APIs -- **Android**: Uses Android SDK and native libraries -- **Permissions**: Automatically handled with user prompts when required -- **Fallbacks**: Graceful degradation when features aren't available - -- Each API documentation includes complete error handling examples and best practices. diff --git a/resources/views/docs/mobile/1/apis/push-notifications.md b/resources/views/docs/mobile/1/apis/push-notifications.md index d3b221f2..212bb675 100644 --- a/resources/views/docs/mobile/1/apis/push-notifications.md +++ b/resources/views/docs/mobile/1/apis/push-notifications.md @@ -19,27 +19,12 @@ Requests permission and enrolls the device for push notifications. **Returns:** `void` -```php -PushNotifications::enrollForPushNotifications(); -``` - ### `getPushNotificationsToken()` Retrieves the current FCM token for this device. **Returns:** `string|null` - The FCM token, or `null` if not available -```php -$token = PushNotifications::getPushNotificationsToken(); - -if ($token) { - // Send token to your server - $this->registerTokenWithServer($token); -} else { - // Token not available, enrollment may have failed -} -``` - ## Events ### `TokenGenerated` @@ -52,7 +37,7 @@ Fired when a push notification token is successfully generated. use Livewire\Attributes\On; use Native\Mobile\Events\PushNotification\TokenGenerated; -#[On('native:' . TokenGenerated::class)] +#[On('native:'.TokenGenerated::class)] public function handlePushToken(string $token) { // Send token to your backend @@ -60,65 +45,6 @@ public function handlePushToken(string $token) } ``` -## Example Usage - -```php -use Livewire\Component; -use Livewire\Attributes\On; -use Native\Mobile\Facades\PushNotifications; -use Native\Mobile\Events\PushNotification\TokenGenerated; - -class NotificationManager extends Component -{ - public function promptForPushNotifications() - { - PushNotifications::getPushNotificationsToken(); - } - - #[On('native:'. TokenGenerated::class)] - public function handlePushNotificationsToken(KitchenSinkService $service, $token) - { - $response = $service->sendForPushNotification($token); - - if ($response->successful()) { - nativephp_alert('Push Notification Sent!', - 'Push notifications will not display while the app is open, close the app and wait one minute to see the notification.'); - } - } - - public function render() - { - return view('livewire.notification-manager'); - } -} -``` - -## Configuration Requirements - -### Firebase Setup - -1. Create a Firebase project at [Firebase Console](https://console.firebase.google.com/) -2. Add your mobile app to the project -3. Download `google-services.json` (Android) and `GoogleService-Info.plist` (iOS) -4. Place these files in your Laravel project root -5. Enable push notifications in your NativePHP config: - -```php -// config/nativephp.php -return [ - 'permissions' => [ - 'push_notifications' => true, - ], -]; -``` - -### Environment Variables - -```bash -NATIVEPHP_APP_ID=com.yourcompany.yourapp -FIREBASE_PROJECT_ID=your-firebase-project-id -``` - ## Permission Flow 1. User taps "Enable Notifications" @@ -130,43 +56,8 @@ FIREBASE_PROJECT_ID=your-firebase-project-id 7. Backend stores token for user 8. Server can now send notifications to this device -## Error Handling - -```php -public function handleRegistrationFailure() -{ - // Common failure scenarios: - - // 1. User denied permission - if (!$this->hasNotificationPermission()) { - $this->showPermissionExplanation(); - return; - } - - // 2. Network error - if (!$this->hasNetworkConnection()) { - $this->showNetworkError(); - return; - } - - // 3. Firebase configuration missing - if (!$this->hasFirebaseConfig()) { - Log::error('Firebase configuration missing'); - return; - } - - // 4. Backend API error - $this->showGenericError(); -} -``` - - ## Best Practices - Request permission at the right time (not immediately on app launch) - Explain the value of notifications to users - Handle permission denial gracefully -- Clean up invalid tokens on your backend -- Implement retry logic for network failures -- Log registration events for debugging -- Respect user preferences and provide opt-out diff --git a/resources/views/docs/mobile/1/apis/secure-storage.md b/resources/views/docs/mobile/1/apis/secure-storage.md index ff95b05e..14256a6e 100644 --- a/resources/views/docs/mobile/1/apis/secure-storage.md +++ b/resources/views/docs/mobile/1/apis/secure-storage.md @@ -5,7 +5,8 @@ order: 700 ## Overview -The SecureStorage API provides secure storage using the device's native keychain (iOS) or keystore (Android) for sensitive data like tokens, passwords, and user credentials. +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; @@ -24,13 +25,7 @@ Stores a secure value in the native keychain or keystore. **Returns:** `bool` - `true` if successfully stored, `false` otherwise ```php -$success = SecureStorage::set('api_token', 'abc123xyz'); - -if ($success) { - // Token stored securely -} else { - // Storage failed -} +SecureStorage::set('api_token', 'abc123xyz'); ``` ### `get()` @@ -44,14 +39,6 @@ Retrieves a secure value from the native keychain or keystore. ```php $token = SecureStorage::get('api_token'); - -if ($token) { - // Use the retrieved token - $this->authenticateWithToken($token); -} else { - // Token not found, user needs to login - $this->redirectToLogin(); -} ``` ### `delete()` @@ -84,18 +71,16 @@ Deletes a secure value from the native keychain or keystore. - **System Protection:** Protected by device authentication - **Tamper Resistance:** Hardware-backed security when available -## Best Practices - -### What to Store +## 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 +## What NOT to Store - Large amounts of data (use encrypted database instead) -- Non-sensitive configuration +- Non-sensitive data - Temporary data - Cached content diff --git a/resources/views/docs/mobile/1/apis/system.md b/resources/views/docs/mobile/1/apis/system.md index aec383fd..de949e96 100644 --- a/resources/views/docs/mobile/1/apis/system.md +++ b/resources/views/docs/mobile/1/apis/system.md @@ -23,33 +23,14 @@ Toggles the device flashlight (camera flash LED) on and off. System::flashlight(); // Toggle flashlight state ``` -## Example Usage +### `isIos()` -```php -use Livewire\Component; -use Native\Mobile\Facades\System; +Determines if the current device is running iOS. -class FlashlightController extends Component -{ - public bool $isFlashlightOn = false; - - public function toggleFlashlight() - { - System::flashlight(); - $this->isFlashlightOn = !$this->isFlashlightOn; - } - - public function render() - { - return view('livewire.flashlight-controller'); - } -} -``` +**Returns:** `true` if iOS, `false` otherwise + +### `isAndroid()` -## Platform Support +Determines if the current device is running Android. -### Flashlight -- **iOS:** Controls camera flash LED -- **Android:** Controls camera flash LED -- **Permissions:** None required -- **Limitations:** May not work if camera is currently in use \ No newline at end of file +**Returns:** `true` if Android, `false` otherwise diff --git a/resources/views/docs/mobile/1/concepts/ci-cd.md b/resources/views/docs/mobile/1/concepts/ci-cd.md index 9e13029a..0e05bd2c 100644 --- a/resources/views/docs/mobile/1/concepts/ci-cd.md +++ b/resources/views/docs/mobile/1/concepts/ci-cd.md @@ -5,7 +5,8 @@ order: 500 ## Overview -NativePHP 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. +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 @@ -13,7 +14,7 @@ NativePHP Mobile provides robust CLI commands designed for automated CI/CD envir Install NativePHP dependencies in automated environments: -```bash +```shell # Install Android platform, overwriting existing files php artisan native:install android --force --no-tty @@ -28,7 +29,7 @@ php artisan native:install both --force Build your app for different environments: -```bash +```shell # Build debug version (development) php artisan native:run android --build=debug --no-tty @@ -41,8 +42,6 @@ php artisan native:run android --build=bundle --no-tty ### Packaging Command -> **Note**: ICU support is currently only available on Android. We are working to add iOS support as soon as possible and will remove this note when it becomes available. - Package signed releases for distribution: ```bash @@ -63,11 +62,6 @@ 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" - -# App Configuration -NATIVEPHP_APP_ID="com.yourcompany.yourapp" -NATIVEPHP_APP_VERSION="1.0.0" -NATIVEPHP_APP_VERSION_CODE="1" ``` ## Command Line Options diff --git a/resources/views/docs/mobile/1/concepts/databases.md b/resources/views/docs/mobile/1/concepts/databases.md index b84e3d1e..4e66ca96 100644 --- a/resources/views/docs/mobile/1/concepts/databases.md +++ b/resources/views/docs/mobile/1/concepts/databases.md @@ -27,27 +27,24 @@ upon foreign key constraints, [you need to enable SQLite support for them](https **It's important to test your migrations on prod builds before releasing updates!** You don't want to accidentally delete your user's data when they update your app. -## Seeding Data with Migrations +## 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: +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 device -- **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 +- **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 +### Creating seed migrations Create dedicated migrations for seeding data: -```bash -php artisan make:migration seed_default_categories +```shell php artisan make:migration seed_app_settings -php artisan make:migration seed_initial_user_data ``` -### Example: Seeding Default Categories - ```php use Illuminate\Database\Migrations\Migration; use Illuminate\Support\Facades\DB; @@ -61,44 +58,42 @@ return new class extends Migration ['name' => 'Personal', 'color' => '#10B981'], ]); } - - public function down() - { - // Rollback/fresh migrations never run - } }; ``` -### Best Practices for Seed Migrations +### Test thoroughly -1. **Use specific timestamps**: Name migrations with dates to ensure proper ordering -2. **Check before inserting**: Prevent duplicate data with updateOrCreate() or firstOrCreate() -3. **Handle conflicts gracefully**: Check if data already exists before seeding -4. **Use realistic data**: Seed with data that matches your production environment -5. **Test thoroughly**: Verify seed migrations work on fresh installs and updates +This is the most important step when releasing new versions of your app, especially with new migrations. -This approach ensures your mobile app has the initial data it needs while maintaining consistency across different app versions and user devices. +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. -## Database Security & Remote Data +## Can I get MySQL/Postgres/other support? + +No. -### Why No MySQL/PostgreSQL Support? +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? -NativePHP for Mobile intentionally does not include MySQL, PostgreSQL, or other remote database drivers. This is a deliberate security decision to prevent developers from accidentally embedding production database credentials directly in mobile applications. +- 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. -**Key security concerns:** -- Mobile apps are distributed to user devices and can be reverse-engineered -- Database credentials embedded in apps are 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 on mobile +## API-first -### The API-First Approach +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. -Instead of direct database connections, we strongly recommend building a secure API backend that your mobile app communicates with. This provides multiple security and architectural benefits: +This provides multiple security and architectural benefits: **Security Benefits:** - Database credentials never leave your server @@ -113,36 +108,42 @@ Instead of direct database connections, we strongly recommend building a secure - Version your API for backward compatibility - Transform data specifically for mobile consumption -### Recommended Architecture +### Securing your API -```php -// ❌ NEVER DO THIS - Direct database in mobile app -DB::connection('production')->table('users')->get(); // Credentials exposed! +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. -// βœ… DO THIS - Secure API communication -$response = Http::withToken($this->getStoredToken()) - ->get('https://your-api.com/api/users'); -``` +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. -### Laravel Sanctum Integration +Store these tokens on your users' devices securely with the [`SecureStorage`](/docs/mobile/1/apis/secure-storage) API. -[Laravel Sanctum](https://laravel.com/docs/sanctum) is the perfect solution for API authentication between your mobile app and Laravel backend. It provides secure, token-based authentication without the complexity of OAuth. +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. -### Best Practices + + +#### Considerations + +In your mobile apps: + +- Always store API tokens using `SecureStorage` - Use HTTPS for all API communications -- Implement retry logic with exponential backoff +- Cache data locally using SQLite for offline functionality +- Check for connectivity before making API calls -**For API Backends:** -- Use Laravel Sanctum or similar for token-based authentication +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 - -This approach ensures your mobile app remains secure while providing seamless access to your backend data through a well-designed API layer. diff --git a/resources/views/docs/mobile/1/concepts/deep-links.md b/resources/views/docs/mobile/1/concepts/deep-links.md index 12912676..3bb8a305 100644 --- a/resources/views/docs/mobile/1/concepts/deep-links.md +++ b/resources/views/docs/mobile/1/concepts/deep-links.md @@ -1,249 +1,92 @@ --- -title: Deep, Universal, App Links and NFC +title: Deep Links order: 300 --- ## Overview -NativePHP for Mobile supports both **deep linking** and **web-based linking** into your mobile apps. +NativePHP for Mobile supports **deep linking** into your app via Custom URL Schemes and Associated Domains: -There are two types of link integrations you can configure: +- **Custom URL Scheme** + ``` + myapp://some/path + ``` +- **Associated Domains** (a.k.a. Universal Links on iOS, App Links on Android) + ``` + https://example.net/some/path + ``` -- **Deep Links** (myapp://some/path) -- **Universal Links (iOS)** and **App Links (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 case, and NativePHP handles all the platform-specific configuration automatically when you provide the proper environment variables. +Each method has its use cases, and NativePHP handles all the platform-specific configuration automatically when you +provide the proper environment variables. ---- - -## Deep Links - -Deep links use a **custom URL scheme** to open your app. - -For example: - -``` -myapp://profile/123 -``` - -When a user taps a deep link, the mobile operating system detects the custom scheme and opens your app directly. +You can even use both approaches at the same time in a single app! -### Configuration +## Custom URL Scheme -To enable deep linking, you must define: +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. -- **Scheme**: The protocol (e.g., myapp) -- **Host**: An optional domain-like segment (e.g., open) +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. -These are configured in your .env: +To enable your app's custom URL scheme, define it in your `.env`: ```dotenv NATIVEPHP_DEEPLINK_SCHEME=myapp -NATIVEPHP_DEEPLINK_HOST=open -``` - -### Platform Behavior - -- **iOS**: Deep links work immediately after installation -- **Android**: Deep links work immediately after installation -- **Both**: Apps will open directly when deep links are tapped - -## Universal Links (iOS) and App Links (Android) - -Universal Links and App Links allow real HTTPS URLs to open your app instead of a web browser, if the app is installed. - -For example: -```dotenv -https://example.net/property/456 ``` -### User Experience +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`). -When a user taps this link: +## Associated domains -- **If your app is installed**: It opens directly into the app -- **If not installed**: It opens normally in the browser -- **Seamless fallback**: No broken experience for users without the app +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 provides a seamless user experience without needing a custom scheme. +This flow increases the opportunity for app discovery dramatically and provides a much better overall user experience. -### How It Works +### How it works -1. You must prove to iOS and Android that you own the domain by hosting special files: +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 Safari or Chrome +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. +**NativePHP handles all the technical setup automatically** - you just need to host the verification files and +configure your domain correctly. -### Configuration - -To enable Universal Links and App Links, you must define: - -- **Host**: The domain name (e.g., example.net) - -These are configured in your .env: - -```dotenv -NATIVEPHP_DEEPLINK_HOST=example.net -``` - -#### Complete Configuration Example +To enable an app-associated domain, define it in your `.env`: ```dotenv -# For both deep links and universal/app links -NATIVEPHP_DEEPLINK_SCHEME=myapp NATIVEPHP_DEEPLINK_HOST=example.net - -# Your app will respond to: -# myapp://profile/123 (deep link) -# https://example.net/profile/123 (universal/app link) -``` - -## Domain Verification - -### Required Files - -The app stores generate the content for these files, but you must host them on your domain: - -#### iOS - `.well-known/apple-app-site-association` - -```json -{ - "applinks": { - "details": [ - { - "appIDs": ["TEAM_ID.com.yourcompany.yourapp"], - "components": [ - { - "*": "*" - } - ] - } - ] - } -} -``` - -#### Android - `.well-known/assetlinks.json` - -```json -[{ - "relation": ["delegate_permission/common.handle_all_urls"], - "target": { - "namespace": "android_app", - "package_name": "com.yourcompany.yourapp", - "sha256_cert_fingerprints": ["SHA256_FINGERPRINT"] - } -}] ``` -### Verification Process +## Testing & troubleshooting -1. **iOS**: Apple's servers periodically check the `apple-app-site-association` file -2. **Android**: Google Play Services verifies the `assetlinks.json` file -3. **Both**: Files must be accessible via HTTPS without redirects -4. **Content-Type**: Serve files as `application/json` - -### Automatic Configuration - -NativePHP automatically: -- Configures iOS `associatedDomains` in your app -- Sets up Android `intentFilters` for your domain -- Generates the correct fingerprints and app IDs -- Handles platform-specific URL routing - -## Platform-Specific Behavior - -### iOS Universal Links - -- **Immediate**: Work as soon as the app is installed -- **Smart Banner**: iOS can display an install banner if app isn't installed -- **Fallback**: Opens in Safari if app isn't installed -- **Cross-app**: Work from any app, not just Safari - -### Android App Links - -- **Verification**: Requires domain verification before working -- **Default**: Can be set as default handler for domain links -- **Fallback**: Opens in Chrome if app isn't installed -- **Intent**: Uses Android's Intent system for routing - -## Handling Universal/App Links - -Once you've configured your deep link settings, you can handle the link in your app. - -Simply set up a route in your web.php file and the deeplink will redirect to your route. - -```dotenv -https://example.net/profile/123 -``` - -```php -Route::get('/profile/{id}', function ($id) { - // Handle the deep link - // This works for both deep links and universal/app links -}); -``` - -## Testing and Development - -### Testing Limitations - -- **Development builds**: Universal/App Links may not work in development -- **Production required**: Full testing requires production builds and domain verification -- **Simulator**: iOS Simulator may not handle Universal Links correctly - -### Best Practices - -1. **Test both link types** - Ensure deep links and universal/app links work -2. **Verify domain files** - Check that .well-known files are accessible -3. **Production testing** - Test universal/app links with production builds -4. **Fallback handling** - Ensure your website handles users without the app -5. **Analytics tracking** - Monitor which link types are most effective - -## NFC - -NFC is a technology that allows you to read and write NFC tags. - -NativePHP handles NFC tag "bumping" just like a Universal/App Link. -You can use a tool like [NFC Tools](https://www.wakdev.com/en/) to write NFC tags. - -Set the url to a Universal/App Link and the tag will be written to the NFC tag. -"Bumping" the tag will open the app. - -### NFC Configuration - -NFC tags work best with Universal/App Links because: -- They provide fallback to website if app isn't installed -- They work across different devices and platforms -- They provide a better user experience than custom schemes - -```bash -# Write this URL to an NFC tag -https://example.net/product/456 - -# When "bumped": -# - Opens your app if installed -# - Opens website if not installed -``` +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. -## Troubleshooting +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. -### Common Issues +There is usually no such limitation for Custom URL Schemes. -1. **Universal Links not working**: Check domain verification files -2. **Deep links not opening**: Verify URL scheme configuration -3. **Wrong app opening**: Check for conflicting URL schemes -4. **iOS Smart Banner**: Ensure proper app store metadata +## Use cases -### Debug Steps +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. -1. **Verify .env configuration** - Check scheme and host values -2. **Test deep links first** - Easier to debug than universal links -3. **Check domain files** - Ensure .well-known files are accessible -4. **Use production builds** - Development builds may not work correctly -5. **Monitor app logs** - Check for link handling errors +They're also more likely to behave the same across both platforms. -Remember that NativePHP handles all the complex platform-specific setup automatically - you just need to configure your domain and environment variables correctly. +Then you could use Universal/App Links in: +- NFC tags +- QR codes +- Email/SMS marketing diff --git a/resources/views/docs/mobile/1/concepts/push-notifications.md b/resources/views/docs/mobile/1/concepts/push-notifications.md index ef65a38e..07ee6d72 100644 --- a/resources/views/docs/mobile/1/concepts/push-notifications.md +++ b/resources/views/docs/mobile/1/concepts/push-notifications.md @@ -5,275 +5,89 @@ order: 400 ## Overview -NativePHP for Mobile uses Firebase Cloud Messaging (FCM) to send push notifications to your users on both iOS and Android devices. +NativePHP for Mobile uses Firebase Cloud Messaging (FCM) to send push notifications to your users on both iOS and +Android devices. -**Cross-Platform Support**: FCM is the unified push notification service for both platforms. For iOS devices, FCM automatically routes notifications through Apple Push Notification Service (APNS) behind the scenes - you don't need to configure APNS separately. +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. -**Supported Services**: NativePHP only supports FCM. Other push notification services are not supported. +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. -## Setting up your app +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 Project Setup + -For server-side notifications, you'll also need a Firebase service account: +## Firebase -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` in your Laravel project's `public` directory +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. -### NativePHP Configuration +You can ignore Firebase's further setup instructions as this is already taken care of by NativePHP. -Simply drag the `google-services.json` file into the root of your Laravel project, enable `push_notifications` in the config and it will be used automatically. +### Service account -You will see more instructions on how to configure your app in the Firebase documentation, you can ignore all of those, NativePHP handles all of that for you. +For sending push notifications from your server-side application, you'll also need a Firebase service account: -## Receiving Push Tokens +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 -### Token Management +## Getting push tokens -FCM tokens are unique identifiers for each app installation. These tokens can change when: +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 on Android +- The app is updated - Other internal FCM operations -You should store both the FCM token and platform information for each user device. - -### Listening for Tokens - -To receive push notifications, you must register a listener for the event. For example, take a look at how easy it is to listen for a `TokenGenerated` event in Livewire: +To request a token, use the `PushNotifications::getPushNotificationsToken()` method: ```php -use Livewire\Attributes\On; -use Livewire\Component; use Native\Mobile\Facades\PushNotifications; -use Native\Mobile\Events\PushNotification\TokenGenerated; - -class PushNotifications extends Component -{ - public function render() - { - return view('livewire.system.push-notifications'); - } - - #[On('native:' . TokenGenerated::class)] - public function handlePushNotifications(string $token) - { - // Do something with the token... - } -} -``` - -Because of the nature of mobile applications you need an api server to handle these tokens. You can use Laravel's built-in `Http` facade to `POST` the token to your server, on the server side you need to associate the token with the "user" that owns the device. -We **strongly** recommend using [Sanctum](https://laravel.com/docs/sanctum) to handle this for you. - -## The flow - -Your app authenticates users against your own api server, when users create an account or login the server validates and authenticates the user and passes back a Sanctum token. - -The token is stored in your apps `session` and is used on subsequent requests to the api server. - -When a push notification is received, the token is sent to your api server and the server stores it for the user who sent it. - -> Optionally, you can have a `HasMany` relationship between your users and devices, this allows you to associate a device with a user and then use the device's token to send push notifications to that users devices. - -## Sending Push Notifications - -Once you have the token, you may use it from your server-based applications to trigger Push Notifications directly to your user's device. We use the `google/apiclient` package to send the notifications. - -```bash -composer require google/apiclient +PushNotifications::getPushNotificationsToken(); ``` -This is the exact code used by the NativePHP Kitchen Sink App: +If the user has approved your app to use push notifications and the request to FCM succeeded, a `TokenGenerated` event +will fire. -```php -Route::group(['middleware' => 'auth:sanctum'], function () { - Route::post('send-push-notification', PushNotificationController::class)->name('send-push-notification'); -}); -``` +Listen for this event to receive the token. Here's an example in a Livewire component: ```php -namespace App\Http\Controllers; - -use App\Jobs\SendPushNotification; -use Illuminate\Http\Request; +use App\Services\APIService; +use Livewire\Attributes\On; +use Native\Mobile\Facades\PushNotifications; +use Native\Mobile\Events\PushNotification\TokenGenerated; -class PushNotificationController extends Controller +class PushNotifications extends Component { - public function __invoke(Request $request) + #[On('native:'.TokenGenerated::class)] + public function storePushToken(APIService $api, string $token) { - $token = $request->get('token'); - - $request->user()->update([ - 'push_token' => $token - ]); - - SendPushNotification::dispatch($token)->delay(now()->addMinutes(1)); + $api->storePushToken($token); } } ``` -## SendPushNotification Job - -Create a job file at `app/Jobs/SendPushNotification.php` with the following structure: +## Sending push notifications -**Key Components:** -- Uses `Google_Client` to authenticate with Firebase -- Retrieves access token from service account JSON file -- Sends HTTP POST request to FCM API endpoint -- Includes notification title and body in the message payload +Once you have a token, you may use it from your server-side applications to trigger Push Notifications directly to your +user's device. -**Required Setup:** -1. Place your `fcm-service-account.json` file in the `public` directory -2. Configure `services.fcm.project_id` in your config -3. Install the `google/apiclient` package + diff --git a/resources/views/docs/mobile/1/concepts/splash-screen-icons.md b/resources/views/docs/mobile/1/concepts/splash-screen-icons.md deleted file mode 100644 index 1a46bed6..00000000 --- a/resources/views/docs/mobile/1/concepts/splash-screen-icons.md +++ /dev/null @@ -1,359 +0,0 @@ ---- -title: Splash Screen/Icons -order: 500 ---- - -## Overview - -App icons and splash screens are the first things users see when interacting with your mobile app. NativePHP Mobile makes it easy to customize both elements to create a professional, branded experience. - -## App Icons - -### Basic Icon Setup - -Place a single high-resolution icon file at: `public/icon.png` - -### Requirements -- **Format:** PNG -- **Size:** 1024 Γ— 1024 pixels -- **Shape:** Square -- **Background:** Transparent or solid (your choice) -- **Content:** Should work well at small sizes - -``` -your-laravel-app/ -β”œβ”€β”€ public/ -β”‚ └── icon.png ← Place your 1024x1024 icon here -β”œβ”€β”€ app/ -└── ... -``` - -### Automatic Icon Generation - -NativePHP automatically generates all required icon sizes for both platforms: - -#### iOS Icon Sizes (Generated Automatically) -- App Store: 1024x1024 -- iPhone: 60x60, 120x120, 180x180 -- iPad: 76x76, 152x152, 167x167 -- Settings: 29x29, 58x58, 87x87 -- Spotlight: 40x40, 80x80, 120x120 - -#### Android Icon Sizes (Generated Automatically) -- mdpi: 48x48 -- hdpi: 72x72 -- xhdpi: 96x96 -- xxhdpi: 144x144 -- xxxhdpi: 192x192 - -### Icon Design Best Practices - -```php -// Example of checking if custom icon exists -class IconValidator -{ - public function validateIcon(): array - { - $iconPath = public_path('icon.png'); - - if (!file_exists($iconPath)) { - return ['valid' => false, 'message' => 'Icon file not found']; - } - - $imageInfo = getimagesize($iconPath); - - if (!$imageInfo) { - return ['valid' => false, 'message' => 'Invalid image file']; - } - - [$width, $height] = $imageInfo; - - if ($width !== 1024 || $height !== 1024) { - return [ - 'valid' => false, - 'message' => "Icon must be 1024x1024px, got {$width}x{$height}px" - ]; - } - - if ($imageInfo['mime'] !== 'image/png') { - return ['valid' => false, 'message' => 'Icon must be PNG format']; - } - - return ['valid' => true, 'message' => 'Icon is valid']; - } -} -``` - -#### Design Guidelines -1. **Keep it simple** - Icons must be recognizable at 16x16 pixels -2. **Avoid text** - Text becomes unreadable at small sizes -3. **Use strong contrast** - Ensure visibility on various backgrounds -4. **Make it memorable** - Unique shape or color helps recognition -5. **Test at multiple sizes** - Check how it looks when scaled down -6. **Consider platform conventions** - iOS prefers rounded corners (applied automatically) - -## Splash Screens - -### Splash Screen Configuration - -Splash screens are shown while your app loads. NativePHP provides built-in splash screen support that you can customize. - -### Default Splash Screen - -By default, NativePHP creates a simple splash screen using your app icon and name. No additional configuration required. - -### Custom Splash Screen - -Create custom splash screen assets: - -``` -your-laravel-app/ -β”œβ”€β”€ public/ -β”‚ β”œβ”€β”€ icon.png -β”‚ β”œβ”€β”€ splash-logo.png ← Optional custom splash logo -β”‚ └── splash-background.png ← Optional background image -β”œβ”€β”€ app/ -└── ... -``` - -### Splash Screen Specifications - -#### iOS Launch Images -- **iPhone:** Various sizes for different devices -- **iPad:** Portrait and landscape orientations -- **Safe Areas:** Account for notches and home indicators - -#### Android Splash Screens -- **Centered Logo:** Displayed on colored background -- **Responsive:** Adapts to different screen sizes and orientations -- **Theme-aware:** Can adapt to light/dark themes - -### Configuration Options - -```php -// config/nativephp.php -return [ - 'app' => [ - 'name' => 'Your App Name', - 'splash' => [ - 'background_color' => '#ffffff', - 'logo_path' => 'splash-logo.png', - 'show_loading' => true, - ], - ], -]; -``` - -### Dynamic Splash Screens - -```php -class SplashScreenManager -{ - public function configureSplashScreen(): void - { - $isDarkMode = $this->getUserPreference('dark_mode'); - - $splashConfig = [ - 'background_color' => $isDarkMode ? '#000000' : '#ffffff', - 'logo_path' => $isDarkMode ? 'logo-dark.png' : 'logo-light.png', - 'show_loading' => true, - ]; - - $this->updateSplashConfiguration($splashConfig); - } - - private function getUserPreference(string $key): bool - { - return session($key, false); - } - - private function updateSplashConfiguration(array $config): void - { - // Update runtime splash configuration - config(['nativephp.app.splash' => $config]); - } -} -``` - -## Asset Compilation - -### CSS and JavaScript Assets - -Your mobile app runs locally, so all assets must be compiled before deployment. - -```bash -# Always compile assets before building -npm run build - -# Then build your mobile app -php artisan native:run -``` - -### Build Process Integration - -```json -{ - "scripts": { - "dev": "vite", - "build": "vite build", - "build:mobile": "vite build --mode mobile", - "mobile:prepare": "npm run build:mobile && php artisan optimize" - } -} -``` - -### Asset Optimization for Mobile - -```javascript -// vite.config.js -import { defineConfig } from 'vite'; -import laravel from 'laravel-vite-plugin'; - -export default defineConfig({ - plugins: [ - laravel({ - input: ['resources/css/app.css', 'resources/js/app.js'], - refresh: true, - }), - ], - build: { - rollupOptions: { - output: { - manualChunks: { - vendor: ['lodash', 'axios'], - ui: ['@headlessui/vue', '@heroicons/vue'], - } - } - }, - chunkSizeWarningLimit: 1000, - }, -}); -``` - -## Development Workflow - -### Hot Reload (Experimental) - -For development, you can use the experimental watch flag: - -```bash -php artisan native:run --watch -``` - -### Watch Limitations - -Currently supports: -- βœ… Blade templates -- βœ… Livewire components -- βœ… PHP files -- ❌ Compiled CSS/JS assets -- ❌ Vite builds -- ❌ Inertia.js apps - -### Recommended Development Flow - -```bash -# For Blade/Livewire apps -php artisan native:run --watch - -# For apps with compiled assets (Vue, React, Inertia) -npm run dev & # Run in background -npm run build # Build assets -php artisan native:run # Launch app -``` - -## Testing Icons and Splash Screens - -### Icon Testing Checklist - -```php -class AssetTestSuite -{ - public function testIconExists(): void - { - $this->assertFileExists(public_path('icon.png')); - } - - public function testIconDimensions(): void - { - $iconPath = public_path('icon.png'); - [$width, $height] = getimagesize($iconPath); - - $this->assertEquals(1024, $width); - $this->assertEquals(1024, $height); - } - - public function testIconFormat(): void - { - $iconPath = public_path('icon.png'); - $imageInfo = getimagesize($iconPath); - - $this->assertEquals('image/png', $imageInfo['mime']); - } - - public function testSplashConfiguration(): void - { - $splashConfig = config('nativephp.app.splash'); - - $this->assertIsArray($splashConfig); - $this->assertArrayHasKey('background_color', $splashConfig); - } -} -``` - -### Visual Testing - -1. **Test on multiple devices** - Check how icons look on different screen sizes -2. **Test both orientations** - Portrait and landscape modes -3. **Test theme variations** - Light and dark modes -4. **Test loading states** - Ensure splash screens display properly -5. **Performance testing** - Monitor app launch times - -## Platform-Specific Considerations - -### iOS -- Icons automatically get rounded corners -- Supports Dynamic Type for accessibility -- Requires specific launch image sizes -- Splash screens adapt to safe areas - -### Android -- Icons can be adaptive (foreground + background) -- Supports vector drawables for splash screens -- Material Design guidelines apply -- Supports theme-aware splash screens - -### Cross-Platform Assets - -``` -public/ -β”œβ”€β”€ icon.png # Universal app icon -β”œβ”€β”€ icon-android.png # Android-specific (optional) -β”œβ”€β”€ icon-ios.png # iOS-specific (optional) -β”œβ”€β”€ splash-logo.png # Universal splash logo -β”œβ”€β”€ splash-android.png # Android splash (optional) -└── splash-ios.png # iOS splash (optional) -``` - -## Best Practices - -### Icon Design -1. **Start with vector graphics** - Use SVG or AI files for source -2. **Export high quality** - Use 1024x1024 PNG with no compression -3. **Test readability** - Check visibility at 16x16 pixels -4. **Maintain brand consistency** - Match your web/desktop icons -5. **Consider accessibility** - Ensure sufficient contrast - -### Splash Screen Design -1. **Keep it simple** - Splash screens should load quickly -2. **Match your brand** - Use consistent colors and typography -3. **Don't include text** - Text may not scale properly -4. **Consider loading states** - Show progress if app takes time to load -5. **Test performance** - Long splash screens hurt user experience - -### Asset Management -1. **Optimize file sizes** - Compress images without quality loss -2. **Use appropriate formats** - PNG for icons, WebP for photos -3. **Version your assets** - Track changes to visual elements -4. **Automate generation** - Script the creation of multiple sizes -5. **Test regularly** - Verify assets display correctly after changes \ No newline at end of file diff --git a/resources/views/docs/mobile/1/getting-started/configuration.md b/resources/views/docs/mobile/1/getting-started/configuration.md index 2b385d19..78293577 100644 --- a/resources/views/docs/mobile/1/getting-started/configuration.md +++ b/resources/views/docs/mobile/1/getting-started/configuration.md @@ -5,19 +5,20 @@ 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. +NativePHP for Mobile is designed so that most configuration happens **inside your Laravel application**, without +requiring you to manually open Xcode or Android Studio. -After installation, NativePHP sets up the necessary native scaffolding, but your primary interaction remains inside Laravel itself. - -This page explains the key configuration points you can control directly through Laravel. +This page explains the key configuration points you can control through Laravel. ## The `nativephp.php` Config File -The nativephp.php config file is where you can configure the native project for your application. +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. +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 or changing environment variables. +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 @@ -30,6 +31,42 @@ 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. @@ -41,12 +78,30 @@ The `cleanup_exclude_files` array in the config file allows you to specify files This is useful for removing files like logs or other temporary files. ## Permissions -In general, the app stores don't want apps to request permissions that they don't need. -To enable some permissions your app needs, you simply need to change their values in the permissions section. +In general, the app stores don't want your app to have permissions (a.k.a entitlements) it doesn't need. -```dotenv -biometric -camera -nfc -location +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. + diff --git a/resources/views/docs/mobile/1/getting-started/development.md b/resources/views/docs/mobile/1/getting-started/development.md index 0097512c..4ada4598 100644 --- a/resources/views/docs/mobile/1/getting-started/development.md +++ b/resources/views/docs/mobile/1/getting-started/development.md @@ -3,30 +3,114 @@ title: Development order: 300 --- +## Building -## The `nativephp` Directory +Building your NativePHP apps can be done completely in the browser with the workflows you're already familiar with. -After running: `php artisan native:install` you’ll see a new `nativephp` directory at the root of your Laravel project as well as a `nativephp.php` config file in your config folder in the Laravel root. +This allows you to iterate rapidly on parts like the UI and major functionality, even using your favorite tools for +testing etc. -This folder contains all the native project files that NativePHP generates for you. +But when you want to test _native_ features, then you must run it on a real/emulated device. -You should not need to manually open or edit any native project files under normal circumstances. -NativePHP handles the heavy lifting for you. +Whether you run your native app on an emulated or real device, it will always require compilation after changes have +been made. -## NATIVEPHP_APP_VERSION +We've worked incredibly hard to ensure that your apps will operate almost identically across both platforms - aside +from obvious platform differences. For the most part, you should be able to build without thinking about which platform +your app is running on, but if you do need to, you can check by using one of the following helper methods: -The NATIVEPHP_APP_VERSION environment variable controls your app's versioning behavior. +```php +use Native\Mobile\Facades\System; -When building for Android, NativePHP first copies the relevant Laravel files into a temporary directory, zips them, and embeds the archive into the Android project. When the app boots, it checks the embedded version against the previously installed version. +System::isIos() // -> `true` on iOS +System::isAndroid() // -> `true` on Android +``` -If the versions match, the app uses the existing files without re-extracting the archive. +To compile and run your app, simply run: -If the versions differ β€” or if the version is set to ***DEBUG*** β€” the app updates itself by re-extracting the new bundle. +```shell +php artisan native:run --build=debug +``` -This mechanism ensures developers can iterate quickly during development, while providing a faster, more stable experience for end users once an app is published. +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. -> Rule of Thumb: -> During development, keep NATIVEPHP_APP_VERSION set to DEBUG to always refresh the app. -> When preparing a new release, update it to a semantic version (e.g., 1.2.3) to enable versioned updates for your users. + + +## 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 (Experimental) + +You can enable hot reloading by adding the `--watch` flag when running the `native:run` command: + +```shell +php artisan native:run --watch +``` + +This is useful during development for quickly testing changes without rebuilding the entire app. + +### Caveats + +- This feature is currently best suited for **Blade** and **Livewire** applications. +- It does **not** currently detect or sync **compiled frontend assets**, such as those built with Vite or used by + **Inertia.js**. +- If you're working with a JavaScript-heavy stack (Vue, React, Inertia), you should continue + [building your frontend](/docs/mobile/1/the-basics/assets) before launching the app with `native:run`. + +## 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/1/getting-started/environment-setup.md b/resources/views/docs/mobile/1/getting-started/environment-setup.md index 2f955a04..561a5c95 100644 --- a/resources/views/docs/mobile/1/getting-started/environment-setup.md +++ b/resources/views/docs/mobile/1/getting-started/environment-setup.md @@ -3,17 +3,32 @@ 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 -### For iOS -1. macOS (required - iOS development is only possible on Mac) + + +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 (for dependency management) -5. CocoaPods -6. _Optional_ iOS device for testing +4. Homebrew & CocoaPods +5. _Optional_ iOS device for testing -#### Setting up iOS Development Environment +### Setting up iOS Development Environment 1. **Install Xcode** - Download from the [Mac App Store](https://apps.apple.com/app/xcode/id497799835) @@ -42,24 +57,28 @@ order: 100 pod --version ``` -#### Apple Developer Account +### 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 -> **Note** You cannot build iOS apps on Windows or Linux - ## Android Requirements -### For Android 1. [Android Studio 2024.2.1 or later](https://developer.android.com/studio) 2. Android SDK with API 23 or higher 3. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed. -> **Note** You do not need to separately install the Java Development Kit (JDK). Android Studio will automatically install the proper JDK for you. + + +### Setting up Android Studio and SDK 1. **Download and Install Android Studio** - Download from the [Android Studio download page](https://developer.android.com/studio) @@ -75,20 +94,39 @@ to develop and test your apps on a Simulator. However, you will need to enroll w That's it! Android Studio handles all the necessary configuration automatically. +### Preparing for NativePHP + +1. Check that you can run `java -v` and `adb devices` from the terminal. +2. The following environment variables set: + +#### On macOS +```shell +export JAVA_HOME=$(/usr/libexec/java_home -v 17) // This isn't required if JAVA_HOME is already set in your environment variables (check using `printenv | grep JAVA_HOME`) +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 +```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 +``` + ## 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. - -### Running on a real device +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 +### 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 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/1/getting-started/installation.md b/resources/views/docs/mobile/1/getting-started/installation.md index cf99593e..a9f64b18 100644 --- a/resources/views/docs/mobile/1/getting-started/installation.md +++ b/resources/views/docs/mobile/1/getting-started/installation.md @@ -3,63 +3,33 @@ title: Installation order: 100 --- -## Requirements +## Get a license -1. PHP 8.3+ -2. Laravel 10 or higher -3. [A NativePHP for Mobile license](https://nativephp.com/mobile) +Before you begin, you will need to [purchase a license](/mobile). -### For iOS -1. An Apple Silicon Mac running macOS 12+ with [Xcode 16+](https://apps.apple.com/app/xcode/id497799835) -2. An active [Apple Developer account](https://developer.apple.com/) -3. _Optional_ iOS device - -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. But you will need to when you want to test your apps on real devices -and start distributing them to your users via the App Store. - -> **Note** You cannot build iOS apps on Windows or Linux - -### For Android -1. [Android Studio Giraffe (or later)](https://developer.android.com/studio) -2. The following environment variables set. -3. You should be able to successfully run `java -v` and `adb devices` from the terminal. -4. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed. - -#### On macOS -```shell -export JAVA_HOME=$(/usr/libexec/java_home -v 17) // This isn't required if JAVA_HOME is already set in your environment variables (check using `printenv | grep JAVA_HOME`) -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 -```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 -``` +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. -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. +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. -## Laravel +Thank you for supporting the project in this way! πŸ™ -NativePHP for Mobile is built to work with Laravel. You can install it into an existing Laravel application, or -[start a new one](https://laravel.com/docs/installation). 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! +## Install the Composer package + Once you have your license, you will need to add the following to your `composer.json`: @@ -76,9 +46,21 @@ Then run: ```shell composer require nativephp/mobile ``` -*If you experience a cURL error when running this command make sure you are running PHP v8.3+ in your CLI.* + -**Windows Performance Tip:** Add `C:\temp` to your Windows Defender exclusions list to significantly speed up composer installs during app compilation. This prevents real-time scanning from slowing down the many temporary files created during the build process. + 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. @@ -86,7 +68,7 @@ email address you used when purchasing your license. Your password is your licen This package contains all the libraries, classes, commands, and interfaces that your application will need to work with iOS and Android. -**Before** running the `install` command it is important to set the following variables in your `.env`: +**Before** running the `install` command, it is important to set the following variables in your `.env`: ```shell NATIVEPHP_APP_ID=com.yourcompany.yourapp @@ -102,6 +84,34 @@ 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 @@ -113,7 +123,7 @@ Once you're ready: php artisan native:run ``` -This will start compiling your application and boot it on whichever device you select. +Just follow the prompts! This will start compiling your application and boot it on whichever device you select. ### Running on a real device @@ -127,4 +137,4 @@ and that it's been added to your Apple Developer account as 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! πŸŽ‰ \ No newline at end of file +And that's it! You should now see your Laravel application running as a native app! πŸŽ‰ diff --git a/resources/views/docs/mobile/1/getting-started/introduction.md b/resources/views/docs/mobile/1/getting-started/introduction.md index 7957c6a1..a4a91c4b 100644 --- a/resources/views/docs/mobile/1/getting-started/introduction.md +++ b/resources/views/docs/mobile/1/getting-started/introduction.md @@ -14,6 +14,19 @@ 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. @@ -40,16 +53,22 @@ You simply interact with an easy-to-use set of functions from PHP and everything 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, including: +Thanks to our custom PHP extension, you can interact with many native APIs today, with more coming all the time, +including: -- Camera & Microphone -- Biometric ID -- Vibration -- Accelerometer, GPS and other sensors -- Push notifications, native alerts and other native UI elements +- πŸ“· 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 ready -to go! +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!](installation)** +**What are you waiting for!? [Let's go!](quick-start)** diff --git a/resources/views/docs/mobile/1/getting-started/quick-start.md b/resources/views/docs/mobile/1/getting-started/quick-start.md new file mode 100644 index 00000000..0e209a59 --- /dev/null +++ b/resources/views/docs/mobile/1/getting-started/quick-start.md @@ -0,0 +1,35 @@ +--- +title: Quick Start +order: 099 +--- + +## Let's go! + + + +Get your first mobile app running in minutes: + +```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](https://play.google.com/store/apps/details?id=com.nativephp.kitchensinkapp) + on Android (coming soon to iOS!) + +Ready to build your first mobile app with PHP? [Let's get started! πŸš€](/docs/mobile/1/getting-started/introduction) diff --git a/resources/views/docs/mobile/1/getting-started/roadmap.md b/resources/views/docs/mobile/1/getting-started/roadmap.md index cc8c7fc7..0991db47 100644 --- a/resources/views/docs/mobile/1/getting-started/roadmap.md +++ b/resources/views/docs/mobile/1/getting-started/roadmap.md @@ -1,30 +1,10 @@ --- title: Roadmap -order: 099 +order: 098 --- -## Current Status - -NativePHP for Mobile v1 is here. While we're still in the process of adding more and more -native API's and other features we believe it's robust enough to build useful applications that can be -distributed to users. - -Presently, NativePHP for Mobile offers the following "native" functionality: - -- Vibrate -- Show Toasts -- Show Alerts -- Share -- Camera -- Flashlight -- Biometric ID -- Push Notifications -- Deep Links -- NFC -- Secure Storage -- Location -- Native image picker -- Splash screen +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 @@ -53,3 +33,13 @@ We're working on adding more and more features, including (in no particular orde - Ads - In-app billing + diff --git a/resources/views/docs/mobile/1/getting-started/versioning.md b/resources/views/docs/mobile/1/getting-started/versioning.md index c0d1b7f3..13369dc3 100644 --- a/resources/views/docs/mobile/1/getting-started/versioning.md +++ b/resources/views/docs/mobile/1/getting-started/versioning.md @@ -1,48 +1,69 @@ --- -title: Release Notes -order: 600 +title: Versioning Policy +order: 50 --- -## Version Policy +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. -NativePHP 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 over-the-air (OTA) compatibility. +Our aim is to limit the amount of work you need to do to get the latest updates and ensure everything works. -## Release Types +We will aim to post update instructions with each release. -### Patch Releases -**Laravel/PHP code only** - Bug fixes, new Artisan commands, configuration updates, documentation, and dependency updates that don't affect native code. +## Release types -- Safe to update immediately via `composer update` -- No app rebuild required -- Compatible with existing native builds -- Perfect for OTA updates +### Patch releases -### Minor Releases -**Native code changes** - New native APIs, Kotlin/Swift updates, platform-specific features, or native dependency changes. +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. -- Require rebuilding your app with `php artisan native:install --force` -- Need app store submission for distribution -- Include advance notice and migration guides +These releases should be completely compatible with the existing version of your native applications. -## Support Policy +This means that you can: -### What's Safe to Update -- **Patch releases** - Update immediately without rebuilding your app -- **Minor releases** - Plan for rebuild and app store submission +- Safely update via `composer update`. +- Avoid a complete rebuild (no need to `native:install --force`). +- Allow for easier app updates avoiding the app stores. -### Version Constraints -Use semantic versioning constraints in your `composer.json`: +### 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" + "nativephp/mobile": "~1.1.0" } } ``` This automatically receives patch updates while giving you control over minor releases. -## Your Application Versioning +## 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. -You have complete freedom in versioning your own applications - use semantic versioning, codenames, date-based versions, or any scheme that works for your project. NativePHP Mobile's consistent approach ensures you always understand the impact of framework updates regardless of your chosen versioning strategy. +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/1/the-basics/app-assets.md b/resources/views/docs/mobile/1/the-basics/app-assets.md deleted file mode 100644 index 041012df..00000000 --- a/resources/views/docs/mobile/1/the-basics/app-assets.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: App Assets -order: 200 ---- - -## Customizing Your App Icon - -NativePHP makes it easy to apply a custom app icon to your iOS and Android builds. - -### Step 1: Provide Your Icon - -Place a single high-resolution icon file at: `public/icon.png` - - -### Requirements: -- Format: PNG -- Size: 1024 Γ— 1024 pixels -- Shape: Square -- Background: Transparent or solid β€” your choice - -Note: 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 and active in your local PHP environment for this to work. - ---- - -## Compiling CSS and JavaScript - -Your device behaves like a server, so assets must be compiled before deployment. - -To ensure your latest styles and JavaScript are included, run: `npm run build` before running: `php artisan native:run`. - -If you’ve made changes to your frontend, this step is required to see them reflected in the app. - ---- - -## Using the --watch Flag (Experimental) - -NativePHP includes an experimental `--watch` flag that enables automatic file syncing while the app is running: - -php artisan native:run --watch - -This is useful during development for quickly testing changes without rebuilding the entire app. - -### Caveats - -- This feature is currently best suited for **Blade** and **Livewire** applications. -- It does **not** currently detect or sync **compiled frontend assets**, such as those built with Vite or used by **Inertia.js**. -- If you're working with a JavaScript-heavy stack (Vue, React, Inertia), you should continue using `npm run build` before launching the app with `native:run`. - -### Recommendation - -Use `--watch` when you're iterating on Blade views or Livewire components. For all other use cases, treat this flag as experimental and optional. diff --git a/resources/views/docs/mobile/1/the-basics/app-icon.md b/resources/views/docs/mobile/1/the-basics/app-icon.md new file mode 100644 index 00000000..f20f4dbe --- /dev/null +++ b/resources/views/docs/mobile/1/the-basics/app-icon.md @@ -0,0 +1,24 @@ +--- +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 + +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/1/the-basics/assets.md b/resources/views/docs/mobile/1/the-basics/assets.md new file mode 100644 index 00000000..a38f1f76 --- /dev/null +++ b/resources/views/docs/mobile/1/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/1/the-basics/asynchronous-methods.md b/resources/views/docs/mobile/1/the-basics/asynchronous-methods.md deleted file mode 100644 index 4cc36a87..00000000 --- a/resources/views/docs/mobile/1/the-basics/asynchronous-methods.md +++ /dev/null @@ -1,308 +0,0 @@ ---- -title: Asynchronous Methods -order: 200 ---- - -## Overview - -Many native mobile operations take time to complete and require user interaction. NativePHP Mobile handles these through asynchronous methods that use Laravel's event system to notify your app when operations complete. - -## Understanding Async vs Sync - -### Synchronous Methods ⚑ -Execute immediately and return results directly. - -```php -// These complete instantly -Haptics::vibrate(); -System::flashlight(); -Dialog::toast('Hello!'); -``` - -### Asynchronous Methods πŸ”„ -Trigger operations that complete later and fire events when done. - -```php -// These trigger operations and fire events when complete -Camera::getPhoto(); // β†’ PhotoTaken event -Biometrics::promptForBiometricID(); // β†’ Completed event -PushNotifications::enrollForPushNotifications(); // β†’ TokenGenerated event -``` - -## Event Handling Pattern - -All asynchronous methods follow the same pattern: - -1. **Call the method** to trigger the operation -2. **Listen for events** to handle the result -3. **Update your UI** based on the outcome - -### Basic Event Structure - -```php -use Livewire\Component; -use Livewire\Attributes\On; -use Native\Mobile\Facades\Camera; -use Native\Mobile\Events\Camera\PhotoTaken; - -class PhotoComponent extends Component -{ - public bool $isCapturing = false; - public ?string $photoPath = null; - - // Step 1: Trigger the async operation - public function takePhoto() - { - $this->isCapturing = true; - Camera::getPhoto(); - } - - // Step 2: Handle the result event - #[On('native:' . PhotoTaken::class)] - public function handlePhotoTaken(string $path) - { - $this->isCapturing = false; - $this->photoPath = $path; - } - - public function render() - { - return view('livewire.photo-component'); - } -} -``` - -## Event Naming Convention - -All frontend events use the `native:` prefix to prevent naming collisions: - -```php -// Backend event class -Native\Mobile\Events\Camera\PhotoTaken - -// Frontend Livewire event (with prefix) -native:Native\Mobile\Events\Camera\PhotoTaken -``` - -## Common Async Operations - -### Camera Operations - -```php -use Native\Mobile\Events\Camera\PhotoTaken; -use Native\Mobile\Events\Gallery\MediaSelected; - -class MediaManager extends Component -{ - public function capturePhoto() - { - Camera::getPhoto(); - } - - public function selectFromGallery() - { - Camera::pickImages('images', true); - } - - #[On('native:' . PhotoTaken::class)] - public function handlePhoto(string $path) - { - // Handle captured photo - } - - #[On('native:' . MediaSelected::class)] - public function handleGallerySelection($success, $files, $count) - { - // Handle selected media - } -} -``` - -### Biometric Authentication - -```php -use Native\Mobile\Events\Biometric\Completed; - -class SecureFeature extends Component -{ - public function authenticate() - { - Biometrics::promptForBiometricID(); - } - - #[On('native:' . Completed::class)] - public function handleBiometric(bool $success) - { - if ($success) { - $this->unlockFeature(); - } else { - $this->showAuthError(); - } - } -} -``` - -### Push Notification Registration - -```php -use Native\Mobile\Events\PushNotification\TokenGenerated; - -class NotificationSetup extends Component -{ - public function enableNotifications() - { - PushNotifications::enrollForPushNotifications(); - } - - #[On('native:' . TokenGenerated::class)] - public function handleToken(string $token) - { - // Send token to your backend - $this->registerToken($token); - } -} -``` - -### Location Services - -```php -use Native\Mobile\Events\Geolocation\LocationReceived; -use Native\Mobile\Events\Geolocation\PermissionStatusReceived; - -class LocationTracker extends Component -{ - public function getCurrentLocation() - { - Geolocation::getCurrentPosition(true); // High accuracy - } - - #[On('native:' . LocationReceived::class)] - public function handleLocation($success = null, $latitude = null, $longitude = null, $accuracy = null, $timestamp = null, $provider = null, $error = null) - { - $this->latitude = $latitude; - $this->longitude = $longitude; - } - - #[On('native:' . PermissionStatusReceived::class)] - public function handlePermissionStatus($location, $coarseLocation, $fineLocation) - { - if (!$coarseLocation == 'granted') { - $this->showLocationPermissionRequest(); - } - } -} -``` - -## Loading States - -Provide visual feedback during async operations: - -```php -class LoadingStatesExample extends Component -{ - public bool $isLoading = false; - public string $loadingMessage = ''; - - public function performAsyncOperation() - { - $this->isLoading = true; - $this->loadingMessage = 'Taking photo...'; - - Camera::getPhoto(); - } - - #[On('native:' . PhotoTaken::class)] - public function handleComplete($path) - { - $this->isLoading = false; - $this->loadingMessage = ''; - - // Process result - } - - public function render() - { - return view('livewire.loading-states-example'); - } -} -``` - -## Advanced Patterns - -### Chaining Async Operations - -```php -class ChainedOperations extends Component -{ - public function authenticateAndCapture() - { - // Step 1: Authenticate first - Biometrics::promptForBiometricID(); - } - - #[On('native:' . Completed::class)] - public function handleAuthComplete(bool $success) - { - if ($success) { - // Step 2: Then capture photo - Camera::getPhoto(); - } - } - - #[On('native:' . PhotoTaken::class)] - public function handlePhotoComplete(string $path) - { - // Step 3: Process the authenticated photo - $this->processSecurePhoto($path); - } -} -``` - -### Multiple Event Listeners - -```php -class MultiEventComponent extends Component -{ - public function performMultipleOperations() - { - Camera::getPhoto(); - PushNotifications::enrollForPushNotifications(); - Geolocation::getCurrentPosition(); - } - - #[On('native:' . PhotoTaken::class)] - public function handlePhoto(string $path) { /* ... */ } - - #[On('native:' . TokenGenerated::class)] - public function handlePushToken(string $token) { /* ... */ } - - #[On('native:' . LocationReceived::class)] - public function handleLocation($success = null, $latitude = null, $longitude = null, $accuracy = null) { /* ... */ } -} -``` - -## Troubleshooting - -### Debugging Async Operations - -```php -class DebuggingComponent extends Component -{ - public function startDebugOperation() - { - Log::info('Starting async operation'); - $this->isLoading = true; - - Camera::getPhoto(); - } - - #[On('native:' . PhotoTaken::class)] - public function handleResult($path) - { - Log::info('Async operation completed', ['result' => $result]); - $this->isLoading = false; - } -} -``` - -Understanding asynchronous methods is crucial for building responsive mobile apps with NativePHP. The event-driven pattern ensures your UI stays responsive while native operations complete in the background. diff --git a/resources/views/docs/mobile/1/the-basics/events.md b/resources/views/docs/mobile/1/the-basics/events.md new file mode 100644 index 00000000..07b7b7ae --- /dev/null +++ b/resources/views/docs/mobile/1/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/1/the-basics/icu-support.md b/resources/views/docs/mobile/1/the-basics/icu-support.md deleted file mode 100644 index 3583a7f6..00000000 --- a/resources/views/docs/mobile/1/the-basics/icu-support.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: ICU Support -order: 300 ---- - -## Overview - -ICU (International Components for Unicode) is a library that provides robust Unicode and locale support for applications. While NativePHP Mobile includes a lightweight PHP runtime by default, you can optionally enable ICU support for applications that require advanced internationalization features. - -> **Note**: ICU support is currently only available on Android. We are working to add iOS support as soon as possible and will remove this note when it becomes available. - -## What is ICU? - -ICU provides: -- **Unicode support** - Full Unicode text processing -- **Localization** - Number, date, and currency formatting -- **Collation** - Language-sensitive string comparison -- **Text boundaries** - Word, sentence, and line breaking -- **Transliteration** - Script conversion between languages - -## When Do You Need ICU? - -### Specifically Required for: -- **[Filament](https://filamentphp.com/)** - Uses `intl` extension extensively -- **Laravel's localization helpers** that depend on `intl` -- **Third-party packages** that require `intl` extension -- **Multi-language applications** with complex formatting needs - -## Installation - -### During Initial Setup - -When running `php artisan native:install`, you'll be prompted: - -```bash -php artisan native:install - -# You'll see: -? βž• Include ICU-enabled PHP binary for Filament/intl requirements? (~30MB extra) - > No (default - smaller app size) - Yes (required for Filament and advanced i18n) -``` - -Select **"Yes"** if you need ICU support. - -### After Installation - -If you already installed without ICU and need to add it: - -```bash -# Re-run the installer and select ICU support -php artisan native:install --force -``` - -## Performance Considerations - -### Memory Usage -- ICU adds ~28MB to your app size -- Runtime memory usage increases slightly -- Complex formatting operations are slower diff --git a/resources/views/docs/mobile/1/the-basics/native-functions.md b/resources/views/docs/mobile/1/the-basics/native-functions.md index c90fee2f..6ff841b1 100644 --- a/resources/views/docs/mobile/1/the-basics/native-functions.md +++ b/resources/views/docs/mobile/1/the-basics/native-functions.md @@ -3,11 +3,14 @@ title: Native Functions order: 100 --- -NativePHP for Mobile enables you to build powerful mobile applications using Laravel and PHP. What makes this approach unique is the ability to call native device functions directly from your PHP code, giving you access to platform-specific features while maintaining the productivity and familiarity of Laravel development. +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. -These functions are called from your PHP code using one of an ever-growing list of facades. +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. -All native functionality is namespaced into its own Facade, they are: +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` @@ -17,3 +20,12 @@ All native functionality is namespaced into its own Facade, they are: - `Native\Mobile\Facades\PushNotifications` - `Native\Mobile\Facades\SecureStorage` - `Native\Mobile\Facades\System` + + diff --git a/resources/views/docs/mobile/1/the-basics/overview.md b/resources/views/docs/mobile/1/the-basics/overview.md new file mode 100644 index 00000000..3ef606ce --- /dev/null +++ b/resources/views/docs/mobile/1/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/1/the-basics/splash-screens.md b/resources/views/docs/mobile/1/the-basics/splash-screens.md new file mode 100644 index 00000000..eedcd1d5 --- /dev/null +++ b/resources/views/docs/mobile/1/the-basics/splash-screens.md @@ -0,0 +1,17 @@ +--- +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