diff --git a/resources/views/docs/mobile/3/concepts/queues.md b/resources/views/docs/mobile/3/concepts/queues.md new file mode 100644 index 00000000..67551806 --- /dev/null +++ b/resources/views/docs/mobile/3/concepts/queues.md @@ -0,0 +1,89 @@ +--- +title: Queues +order: 250 +--- + +## Background Queue Worker + +NativePHP runs a background queue worker alongside your app's main thread. Queued jobs execute off the main thread, +so they won't block your UI or slow down user interactions. + +Both iOS and Android are supported. + +## Setup + +Set your queue connection to `database` in your `.env` file: + +```dotenv +QUEUE_CONNECTION=database +``` + +That's it. NativePHP handles the rest — the worker starts automatically when your app boots. + +## Usage + +Use Laravel's standard queue dispatching. Everything works exactly as you'd expect: + +```php +use App\Jobs\SyncData; + +SyncData::dispatch($payload); +``` + +Or using the `dispatch()` helper: + +```php +dispatch(new App\Jobs\ProcessUpload($file)); +``` + +### Example Job + +Here's a simple job that makes an API call in the background: + +```php +namespace App\Jobs; + +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Http; +use NativePHP\Plugins\Dialog\Dialog; + +class SyncData implements ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + public function __construct(public array $payload) {} + + public function handle() + { + Http::post('https://api.example.com/sync', $this->payload); + + Dialog::toast('Sync complete!'); + } +} +``` + +## How It Works + +When your app boots, NativePHP automatically starts a dedicated PHP runtime on a separate thread. This worker +polls `queue:work --once` in a loop, picking up and executing queued jobs as they come in. + +Because it runs on its own thread with its own PHP runtime, your queued jobs are fully isolated from the main +request cycle — long-running tasks won't affect app responsiveness. + + + +## Things to Note + +- The queue worker requires [ZTS (Thread-Safe) PHP](/docs/mobile/3/getting-started/changelog), which is included by default in v3.1+. +- Only the `database` queue connection is supported. This uses the same SQLite database as your app. +- Jobs are persisted to the database, so they survive app restarts. +- If a job fails, Laravel's standard retry and failure handling applies. \ No newline at end of file diff --git a/resources/views/docs/mobile/3/getting-started/changelog.md b/resources/views/docs/mobile/3/getting-started/changelog.md index b5a1ff37..ba5a4d78 100644 --- a/resources/views/docs/mobile/3/getting-started/changelog.md +++ b/resources/views/docs/mobile/3/getting-started/changelog.md @@ -3,4 +3,40 @@ title: Changelog order: 2 --- -For changes prior to v3, see the [v2 documentation](/docs/mobile/2/getting-started/changelog). \ No newline at end of file +For changes prior to v3, see the [v2 documentation](/docs/mobile/2/getting-started/changelog). + +## v3.1 — Persistent Runtime & Performance + +### New Features + +- **Persistent PHP Runtime** — Laravel boots once and the kernel is reused across requests, yielding ~5-30ms response times vs ~200-300ms previously. +- **ZTS (Thread-Safe) PHP** support enabling background queue workers +- **PHP Queue Worker** — a dedicated background thread runs queued Laravel jobs off the main thread on both iOS and Android. Just set `QUEUE_CONNECTION=database` and dispatch jobs as normal. See [Queues](../concepts/queues) for details. +- **Binary caching** — PHP binaries are cached in `nativephp/binaries` to avoid re-downloading on every build +- **Versions manifest** — binary URLs fetched from `versions.json` instead of being hardcoded +- **Android 8+ support** — minimum SDK lowered from Android 13 (API 33) to Android 8 (API 26), dramatically expanding device reach +- **PHP 8.3–8.5 support** — NativePHP now detects your app's PHP version from `composer.json` and matches it automatically, with PHP 8.3 as the lowest supported version +- **ICU/Intl support on iOS** — iOS now ships with full ICU support, enabling Filament and other packages that depend on the `intl` extension to work on both platforms +- **Configurable Android SDK versions** — `compile_sdk`, `min_sdk`, and `target_sdk` in your config +- **Plugin multi-register** — `native:plugin:register` discovers and registers multiple plugins in one pass +- **Unregistered plugin warnings** during `native:run` +- **`ios/i` and `android/a` flags** for the `native:jump` command + +### Improvements + +- Static linking on Android for better performance and reliability +- Plugin compilation during `native:package` builds +- URL encoding preserved on Android redirects +- Removed unused `react/http` and `react/socket` dependencies + +### Developer Experience + +- Laravel Boost skill support (shoutout Pushpak!) LINK TO PRS + +## v3.0 — Plugin Architecture + +- **Plugin-based architecture** — the framework is built around a modular plugin system +- **All core APIs shipped as plugins** — Camera, Biometrics, Dialog, and more are all individual plugins +- **`NativeServiceProvider`** for registering third-party plugins +- **Plugin management commands** — install, register, and manage plugins from the CLI +- **Free and open source** diff --git a/resources/views/docs/mobile/3/getting-started/commands.md b/resources/views/docs/mobile/3/getting-started/commands.md index bc523e56..e500c222 100644 --- a/resources/views/docs/mobile/3/getting-started/commands.md +++ b/resources/views/docs/mobile/3/getting-started/commands.md @@ -32,15 +32,22 @@ Build and run your app on a device or simulator. php artisan native:run {os?} {udid?} ``` -| Option | Description | -|--------|-------------| -| `os` | Target platform: `ios` or `android` | -| `udid` | Specific device/simulator UDID | -| `--build=debug` | Build type: `debug`, `release`, or `bundle` | -| `--watch` | Enable hot reloading during development | -| `--start-url=` | Initial URL/path to load (e.g., `/dashboard`) | +| Option | Description | +|--------|---------------------------------------------------| +| `os` | Target platform: `ios/i` or `android/a` | +| `udid` | Specific device/simulator UDID | +| `--build=debug` | Build type: `debug`, `release`, or `bundle` | +| `--watch` | Enable hot reloading during development | +| `--start-url=` | Initial URL/path to load (e.g., `/dashboard`) | | `--no-tty` | Disable TTY mode for non-interactive environments | + + ### native:watch Watch for file changes and sync to a running mobile app. @@ -49,10 +56,10 @@ Watch for file changes and sync to a running mobile app. php artisan native:watch {platform?} {target?} ``` -| Option | Description | -|--------|-------------| -| `platform` | Target platform: `ios` or `android` | -| `target` | The device/simulator UDID to watch | +| Option | Description | +|--------|-----------------------------------------| +| `platform` | Target platform: `ios/i` or `android/a` | +| `target` | The device/simulator UDID to watch | ### native:jump @@ -62,14 +69,16 @@ Start the NativePHP development server for testing mobile apps without building. php artisan native:jump ``` -| Option | Description | -|--------|-------------| -| `--platform=` | Target platform: `android` or `ios` | -| `--host=0.0.0.0` | Host address to serve on | -| `--http-port=` | HTTP port to serve on | +| Option | Description | +|-----------------------|-------------| +| `--platform=` | Target platform: `android` or `ios` | +| `ios/i` | Shorthand for `--platform=ios` | +| `android/a` | Shorthand for `--platform=android` | +| `--host=0.0.0.0` | Host address to serve on | +| `--http-port=` | HTTP port to serve on | | `--laravel-port=8000` | Laravel dev server port to proxy to | -| `--no-mdns` | Disable mDNS service advertisement | -| `--skip-build` | Skip building if `app.zip` exists | +| `--no-mdns` | Disable mDNS service advertisement | +| `--skip-build` | Skip building if `app.zip` exists | ### native:open @@ -79,9 +88,9 @@ Open the native project in Xcode or Android Studio. php artisan native:open {os?} ``` -| Option | Description | -|--------|-------------| -| `os` | Target platform: `ios` or `android` | +| Option | Description | +|--------|-----------------------------------------| +| `os` | Target platform: `ios/i` or `android/a` | ### native:tail @@ -119,12 +128,12 @@ Package your app for distribution with signing. php artisan native:package {platform} ``` -| Option | Description | -|--------|-------------| -| `platform` | Target platform: `android` or `ios` | -| `--build-type=release` | Build type: `release` or `bundle` | -| `--output=` | Output directory for signed artifacts | -| `--jump-by=` | Skip ahead in version numbering | +| Option | Description | +|--------|---------------------------------------------------| +| `platform` | Target platform: `android/a` or `ios/i` | +| `--build-type=release` | Build type: `release` or `bundle` | +| `--output=` | Output directory for signed artifacts | +| `--jump-by=` | Skip ahead in version numbering | | `--no-tty` | Disable TTY mode for non-interactive environments | **Android Options:** @@ -181,10 +190,10 @@ Generate signing credentials for iOS and Android. php artisan native:credentials {platform?} ``` -| Option | Description | -|--------|-------------| -| `platform` | Target platform: `android`, `ios`, or `both` | -| `--reset` | Generate new keystore and PEM certificate | +| Option | Description | +|--------|--------------------------------------------------| +| `platform` | Target platform: `android/a`, `ios/i`, or `both` | +| `--reset` | Generate new keystore and PEM certificate | ### native:check-build-number @@ -219,15 +228,15 @@ php artisan native:plugin:list ### native:plugin:register -Register a plugin in your NativeServiceProvider. +Register a plugin in your NativeServiceProvider. When called without arguments, discovers all unregistered plugins and lets you register them. ```shell -php artisan native:plugin:register {plugin} +php artisan native:plugin:register {plugin?} ``` | Option | Description | |--------|-------------| -| `plugin` | Package name (e.g., `vendor/plugin-name`) | +| `plugin` | Package name (e.g., `vendor/plugin-name`). Optional — omit to discover unregistered plugins | | `--remove` | Remove the plugin instead of adding it | | `--force` | Skip conflict warnings | diff --git a/resources/views/docs/mobile/3/getting-started/configuration.md b/resources/views/docs/mobile/3/getting-started/configuration.md index 5b8eae02..6481e0b5 100644 --- a/resources/views/docs/mobile/3/getting-started/configuration.md +++ b/resources/views/docs/mobile/3/getting-started/configuration.md @@ -56,78 +56,68 @@ Note that this will make your application's boot up slightly slower as it must u 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 +## Persistent Runtime -The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file -before bundling. This is useful for removing sensitive information like API keys or other secrets. +v3.1 introduces a persistent PHP runtime that boots Laravel once and reuses the kernel across all subsequent requests. +This dramatically improves performance — from ~200-300ms per request down to ~5-30ms. -## Cleanup `exclude_files` +The `runtime` section controls this behavior: -The `cleanup_exclude_files` array in the config file allows you to specify files and folders that should be removed -before bundling. This is useful for removing files like logs or other temporary files that aren't required for your app -to function and bloat your downloads. +```php +'runtime' => [ + 'mode' => env('NATIVEPHP_RUNTIME_MODE', 'persistent'), // [tl! highlight] + 'reset_instances' => true, + 'gc_between_dispatches' => false, +], +``` -## Permissions -In general, the app stores don't want your app to have permissions (a.k.a entitlements) it doesn't need. +- `mode` — Set to `persistent` (default) to reuse the Laravel kernel, or `classic` to boot/shutdown per request. + If persistent boot fails, it falls back to classic mode automatically. +- `reset_instances` — Whether to clear resolved facade instances between dispatches. (default: `true`) +- `gc_between_dispatches` — Whether to run garbage collection between dispatches. Enable this if you notice memory + growth over time. (default: `false`) -By default, all optional permissions are disabled. + + +## Deep Links + +Configure deep linking to allow URLs to open your app directly: ```php - 'permissions' => [ - 'biometric' => false, - 'camera' => false, - 'location' => false, - 'microphone' => false, - 'microphone_background' => false, - 'network_state' => true, - 'nfc' => false, - 'push_notifications' => false, - 'storage_read' => false, - 'storage_write' => false, - 'scanner' => false, - 'vibrate' => false, - ], +'deeplink_scheme' => env('NATIVEPHP_DEEPLINK_SCHEME'), +'deeplink_host' => env('NATIVEPHP_DEEPLINK_HOST'), ``` -For iOS, this will provide a sensible default description. +The `deeplink_scheme` enables custom URL schemes (e.g. `myapp://some/path`), while `deeplink_host` enables +verified HTTPS links and NFC tags (e.g. `https://your-host.com/path`). -### Custom permission descriptions +See the [Deep Links](../concepts/deep-links) documentation for full details. -For iOS, it's possible to define custom permission descriptions. In most cases, you are required to provide clear -reasons why your app needs certain permissions. You can do this easily from the config file: +## Start URL + +Set the initial path that loads when your app starts: ```php - 'permissions' => [ - 'biometric' => 'Access to the biometric sensor is needed to secure user resources', - //... - ], +'start_url' => env('NATIVEPHP_START_URL', '/'), ``` -### 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. Required for taking photos and - recording video. Note that the user may deny access and any camera functions will then result in a no-op. -- `nfc` - Allows your application to request access to the device's NFC reader, if present. -- `push_notifications` - Allows your application to request permissions to send push notifications. Note that the user - may deny this and any push notification functions will then result in a no-op. -- `location` - Allows your application to request access to the device's GPS receiver, if present. Note that the user - may deny this and any location functions will then result in a no-op. -- `vibrate` - In modern Android devices this is a requirement for most haptic feedback. -- `storage_read` - Grants your app access to read from device storage locations. This is not required for basic app file manipulation. -- `storage_write` - Allows your app to write to device storage. This is not required for basic app file manipulation. -- `microphone` - Allows your application to request access to the device's microphone, if present. Required for audio - recording functionality. Note that the user may deny access and any microphone functions will then result in a no-op. -- `microphone_background` - Allows your application to request access to the device's microphone, if present. Required - for audio recording functionality. Note that the user may deny access and any microphone functions will then result in - a no-op. -- `scanner` - Allows your application to scan QR codes and barcodes. Note that the user may deny camera access and any - scanning functions will then result in a no-op. -- `network_state` - Allows your application to access information about the device's network connectivity status. This - permission is enabled by default as it's commonly needed for basic network state detection. +This is useful if you want to land users on a specific page like `/dashboard` or `/onboarding` instead of the root. + +## Cleanup `env` keys + +The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file +before bundling. This is useful for removing sensitive information like API keys or other secrets. + +## Cleanup `exclude_files` + +The `cleanup_exclude_files` array in the config file allows you to specify files and folders that should be removed +before bundling. This is useful for removing files like logs or other temporary files that aren't required for your app +to function and bloat your downloads. ## Orientation @@ -173,3 +163,155 @@ Once you've published an app with iPad support, it cannot be undone. If you wish will need to change your `NATIVEPHP_APP_ID` and publish the app under a new App Store listing. + +## Android SDK Versions + +The `android` section of your config file lets you control which Android SDK versions are used when building your app. +These are nested under the `android` key in `config/nativephp.php`: + +```php +'android' => [ + 'compile_sdk' => env('NATIVEPHP_ANDROID_COMPILE_SDK', 36), + 'min_sdk' => env('NATIVEPHP_ANDROID_MIN_SDK', 33), + 'target_sdk' => env('NATIVEPHP_ANDROID_TARGET_SDK', 36), +], +``` + +- `compile_sdk` - The SDK version used to compile your app. This determines which Android APIs are available to you + at build time. (default: `36`) +- `min_sdk` - The minimum Android version your app supports. Devices running an older version won't be able to install + your app. (default: `26`, Android 8) +- `target_sdk` - The SDK version your app is designed and tested against. Google Play uses this to apply appropriate + compatibility behaviors. (default: `36`) + +You can also set these via environment variables: + +```dotenv +NATIVEPHP_ANDROID_COMPILE_SDK=36 +NATIVEPHP_ANDROID_MIN_SDK=26 +NATIVEPHP_ANDROID_TARGET_SDK=36 +``` + + + +## Android Build Configuration + +Fine-tune your Android build process with these options under the `android.build` key: + +```php +'android' => [ + 'build' => [ + 'minify_enabled' => env('NATIVEPHP_ANDROID_MINIFY_ENABLED', false), + 'shrink_resources' => env('NATIVEPHP_ANDROID_SHRINK_RESOURCES', false), + 'obfuscate' => env('NATIVEPHP_ANDROID_OBFUSCATE', false), + 'debug_symbols' => env('NATIVEPHP_ANDROID_DEBUG_SYMBOLS', 'FULL'), + 'parallel_builds' => env('NATIVEPHP_ANDROID_PARALLEL_BUILDS', true), + 'incremental_builds' => env('NATIVEPHP_ANDROID_INCREMENTAL_BUILDS', true), + ], +], +``` + +- `minify_enabled` — Enable R8/ProGuard code shrinking. (default: `false`) +- `shrink_resources` — Remove unused resources from the APK. (default: `false`) +- `obfuscate` — Obfuscate class and method names. (default: `false`) +- `debug_symbols` — Include debug symbols. Set to `FULL` for symbolicated crash reports. (default: `FULL`) +- `parallel_builds` / `incremental_builds` — Gradle build performance options. (default: `true`) + + + +## Android Status Bar Style + +Control the color of the status bar and navigation bar icons: + +```php +'android' => [ + 'status_bar_style' => env('NATIVEPHP_ANDROID_STATUS_BAR_STYLE', 'auto'), +], +``` + +Options: `auto` (detect from system theme), `light` (white icons), or `dark` (dark icons). + +## Development Server + +Configure the development server used by `native:jump` and `native:watch`: + +```php +'server' => [ + 'http_port' => env('NATIVEPHP_HTTP_PORT', 3000), + 'ws_port' => env('NATIVEPHP_WS_PORT', 8081), + 'service_name' => env('NATIVEPHP_SERVICE_NAME', 'NativePHP Server'), + 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', true), +], +``` + +- `http_port` — The port for serving your app during development. (default: `3000`) +- `ws_port` — The WebSocket port for hot reload communication. (default: `8081`) +- `service_name` — The mDNS service name advertised on your network. (default: `NativePHP Server`) +- `open_browser` — Automatically open a browser with a QR code when the server starts. (default: `true`) + +## Hot Reload + +Customize which files trigger hot reloads during development: + +```php +'hot_reload' => [ + 'watch_paths' => [ + 'app', + 'resources', + 'routes', + 'config', + 'public', + ], + 'exclude_patterns' => [ + '\.git', + 'storage', + 'node_modules', + ], +], +``` + +## Development Team (iOS) + +Set your Apple Developer Team ID for code signing: + +```php +'development_team' => env('NATIVEPHP_DEVELOPMENT_TEAM'), +``` + +This is typically detected from your installed certificates, but you can override it here. Find your Team ID +in your Apple Developer account under Membership details. + +## App Store Connect + +Configure automated iOS uploads with the App Store Connect API: + +```php +'app_store_connect' => [ + 'api_key' => env('APP_STORE_API_KEY'), + 'api_key_id' => env('APP_STORE_API_KEY_ID'), + 'api_issuer_id' => env('APP_STORE_API_ISSUER_ID'), + 'app_name' => env('APP_STORE_APP_NAME'), +], +``` + +These credentials are used by `native:package --upload-to-app-store` to upload your IPA directly to +App Store Connect without opening Xcode. + + diff --git a/resources/views/docs/mobile/3/getting-started/environment-setup.md b/resources/views/docs/mobile/3/getting-started/environment-setup.md index 59188752..1847e743 100644 --- a/resources/views/docs/mobile/3/getting-started/environment-setup.md +++ b/resources/views/docs/mobile/3/getting-started/environment-setup.md @@ -67,7 +67,7 @@ to develop and test your apps on a Simulator. However, you will need to enroll w ## Android Requirements 1. [Android Studio 2024.2.1 or later](https://developer.android.com/studio) -2. Android SDK with API 33 or higher +2. Android SDK with API 29 or higher 3. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed. +## WebView Compatibility + +On Android, the web view is powered by the system's built-in WebView component, which varies by device and OS version. +Older Android versions ship with older WebView engines that may not support modern CSS features. + +For example, Tailwind CSS v4 uses `@theme` and other newer CSS features that are not supported on older WebView +versions. If you are targeting a lower `min_sdk` to support older devices, consider using Tailwind CSS v3 or another +CSS framework that generates compatible output. You can configure your minimum SDK version in your +[Android SDK Versions](/docs/mobile/3/getting-started/configuration#android-sdk-versions) settings. + +Always test your app on emulators running your minimum supported Android version to catch these issues early. You can +create emulators for older API levels in Android Studio's Virtual Device Manager. + With just a few small changes, we've been able to define a layout that will work well on a multitude of devices without having to add complex calculations or lots of device-specific CSS rules to our code.