Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9192d51
Add mobile 2.x documentation and version switcher
shanerbaner82 Nov 7, 2025
6da5c5d
Add horizontal scrolling to wide tables in documentation
shanerbaner82 Nov 17, 2025
673125e
Update mobile 2.x documentation with API details and improvements
shanerbaner82 Nov 17, 2025
bbffdc9
Merge branch 'main' into mobile-v2-docs
shanerbaner82 Nov 17, 2025
8b598be
Merge branch 'main' into mobile-v2-docs
simonhamp Nov 25, 2025
c38e116
wip
simonhamp Nov 25, 2025
8f1f400
wip
simonhamp Nov 25, 2025
3589fd5
Bump deps
simonhamp Nov 25, 2025
0cf2b44
Extract class list to element style
simonhamp Nov 26, 2025
247845a
Development and Deployment
simonhamp Nov 26, 2025
632a796
OnNative
simonhamp Nov 26, 2025
493ff3b
Reorg
simonhamp Nov 26, 2025
4e6295f
Simplify
simonhamp Nov 26, 2025
968e85c
Improve
simonhamp Nov 26, 2025
4efa6ea
Add version warning
simonhamp Nov 26, 2025
6c8ed22
Add EDGE intro
simonhamp Nov 26, 2025
d8ef32a
Add image
simonhamp Nov 26, 2025
fe35ec8
Events
simonhamp Nov 27, 2025
28718eb
Updates changelog
shanerbaner82 Nov 27, 2025
a8b9dd2
Remove CI/CD page (now in Deployment)
simonhamp Nov 27, 2025
fbf5c38
Improve EDGE intros
simonhamp Nov 27, 2025
7f3960c
Reorg
simonhamp Nov 27, 2025
1021473
Add JS installation docs
simonhamp Nov 27, 2025
6cc85d1
Reorg
simonhamp Nov 27, 2025
b7bf82e
Improve
simonhamp Nov 27, 2025
34ee895
EDGE
simonhamp Nov 27, 2025
c6cc45f
Icons
simonhamp Nov 27, 2025
389c33c
OnNative
simonhamp Nov 28, 2025
088513c
Fix handler example
simonhamp Nov 28, 2025
a887903
Security and Authentication
simonhamp Nov 28, 2025
27f9b4b
Deprecation
simonhamp Nov 28, 2025
b815117
Cleanup
simonhamp Nov 28, 2025
19b7753
Clean the changelog
simonhamp Nov 28, 2025
9e1be6d
Fix Boost paragraph
simonhamp Nov 28, 2025
13c5dff
Merge branch 'main' into mobile-v2-docs
simonhamp Nov 28, 2025
d653ca5
Remove v1 doc change
simonhamp Nov 28, 2025
c654181
Final tweaks (#234)
shanerbaner82 Nov 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,12 @@ nav.docs-navigation > ul > li > ul {
.dark .prose code {
@apply bg-gray-800 text-purple-300;
}

.prose table {
@apply w-full;
}

.prose :where(table):not(:where([class~='not-prose'] *)) {
display: block;
overflow-x: auto;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
id="mobile-dropdown"
>
<x-navbar.device-dropdown-item
href="/docs/mobile/1/getting-started/introduction"
href="/docs/mobile/2/getting-started/introduction"
title="Documentation"
subtitle="Get started with Mobile"
icon="docs"
Expand Down
10 changes: 10 additions & 0 deletions resources/views/docs/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
1 => '1.x',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need context aware filtering in the algolia results. Once this is merged results from 4 versions will show up (desktop & mobile v1 + v2)

2 => '2.x'
]" />
@elseif($platform === 'mobile')
<livewire:version-switcher :versions="[
1 => '1.x',
2 => '2.x'
]" />
@endif

<x-docs.toc-and-sponsors :tableOfContents="$tableOfContents" />
Expand All @@ -30,6 +35,11 @@
1 => '1.x',
2 => '2.x'
]" />
@elseif($platform === 'mobile')
<livewire:version-switcher :versions="[
1 => '1.x',
2 => '2.x'
]" />
@endif

{{-- Copy as Markdown Button --}}
Expand Down
53 changes: 52 additions & 1 deletion resources/views/docs/mobile/1/apis/system.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ order: 800

## Overview

The System API provides access to basic system functions like flashlight control.
The System API provides access to basic system functions like flashlight control, platform detection, and network status monitoring.

```php
use Native\Mobile\Facades\System;
Expand Down Expand Up @@ -34,3 +34,54 @@ Determines if the current device is running iOS.
Determines if the current device is running Android.

**Returns:** `true` if Android, `false` otherwise

### `getNetworkStatus()`

Gets the current network connection status and details.

**Returns:** `?object` containing network information, or `null` if unavailable

```php
$status = System::getNetworkStatus();

if ($status) {
// Check if connected
if ($status->connected) {
echo "Connected via: " . $status->type; // "wifi", "cellular", "ethernet", or "unknown"

// Check if using expensive/metered connection
if ($status->isExpensive) {
echo "Using cellular data - consider limiting usage";
}

// Check if Low Data Mode is enabled (iOS only)
if ($status->isConstrained) {
echo "Low Data Mode is enabled";
}
} else {
echo "No network connection";
}
}
```

**Response Object Properties:**

- `connected` (bool) - Whether the device has network connectivity
- `type` (string) - Connection type: `"wifi"`, `"cellular"`, `"ethernet"`, or `"unknown"`
- `isExpensive` (bool) - Whether the connection is metered/cellular
- `isConstrained` (bool) - Whether Low Data Mode is enabled (iOS only, always `false` on Android)

**Configuration:**

Network state detection is enabled by default. You can disable it in `config/nativephp.php`:

```php
'permissions' => [
'network_state' => true, // Set to false to disable
],
```

**Platform Notes:**

- **iOS:** Uses `NWPathMonitor` from the Network framework. No additional permissions required.
- **Android:** Requires `ACCESS_NETWORK_STATE` permission (automatically added when enabled)
4 changes: 4 additions & 0 deletions resources/views/docs/mobile/2/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Mobile
order: 1
---
4 changes: 4 additions & 0 deletions resources/views/docs/mobile/2/apis/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: APIs
order: 4
---
201 changes: 201 additions & 0 deletions resources/views/docs/mobile/2/apis/audio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
---
title: Audio
order: 50
---

## Overview

The Audio API provides access to the device's microphone for recording audio. It offers a fluent interface for starting and managing recordings, tracking them with unique identifiers, and responding to completion events.

```php
use Native\Mobile\Facades\Audio;
```

## Methods

### `record()`

Start an audio recording. Returns a `PendingAudioRecorder` instance that controls the recording lifecycle.

```php
Audio::record()->start();
```

### `stop()`

Stop the current audio recording. This dispatches the `AudioRecorded` event with the recording file path.

```php
Audio::stop();
```

### `pause()`

Pause the current audio recording without ending it.

```php
Audio::pause();
```

### `resume()`

Resume a paused audio recording.

```php
Audio::resume();
```

### `getStatus()`

Get the current recording status.

**Returns:** `string` - One of: `"idle"`, `"recording"`, or `"paused"`

```php
$status = Audio::getStatus();

if ($status === 'recording') {
// A recording is in progress
}
```

### `getRecording()`

Get the file path to the last recorded audio file.

**Returns:** `string|null` - Path to the last recording, or `null` if none exists

```php
$path = Audio::getRecording();

if ($path) {
// Process the recording file
}
```

## PendingAudioRecorder

The `PendingAudioRecorder` provides a fluent interface for configuring and starting audio recordings. Most methods return `$this` for method chaining.

### `id(string $id)`

Set a unique identifier for this recording. This ID will be included in the `AudioRecorded` event, allowing you to correlate recordings with completion events.

```php
$recorderId = 'message-recording-' . $this->id;

Audio::record()
->id($recorderId)
->start();
```

### `getId()`

Get the recorder's unique identifier. If no ID was set, one is automatically generated (UUID v4).

```php
$recorder = Audio::record()
->id('my-recording');

$id = $recorder->getId(); // 'my-recording'
```

### `event(string $eventClass)`

Set a custom event class to dispatch when recording completes. By default, `AudioRecorded` is used.

**Throws:** `InvalidArgumentException` if the event class does not exist

```php
use App\Events\VoiceMessageRecorded;

Audio::record()
->event(VoiceMessageRecorded::class)
->start();
```

### `remember()`

Store the recorder's ID in the session for later retrieval. This is useful when the recording completes on the next request.

```php
Audio::record()
->id('voice-note')
->remember()
->start();
```

### `lastId()`

Retrieve the last remembered audio recorder ID from the session. Use this in event listeners to correlate recordings.

```php
use Livewire\Attributes\On;
use Native\Mobile\Events\Audio\AudioRecorded;

#[On('native:'.AudioRecorded::class)]
public function handleAudioRecorded(string $path, string $mimeType, ?string $id)
{
// For comparing with remembered IDs
if ($id === Audio::record()->lastId()) {
$this->saveRecording($path);
}
}
```

### `start()`

Explicitly start the audio recording. This is optional - recordings auto-start if you don't call this method.

**Returns:** `bool` - `true` if recording started successfully, `false` if it failed or was already started

```php
$recorder = Audio::record()->id('my-recording');

if ($recorder->start()) {
// Recording started
} else {
// Recording failed - likely due to permission denial
}
```

## Events

### `AudioRecorded`

Dispatched when an audio recording completes. The event includes the file path and recording ID.

**Payload:**
- `string $path` - File path to the recorded audio
- `string $mimeType` - MIME type of the audio (default: `'audio/m4a'`)
- `?string $id` - The recorder's ID, if one was set

```php
use Livewire\Attributes\On;
use Native\Mobile\Events\Audio\AudioRecorded;

#[On('native:'.AudioRecorded::class)]
public function handleAudioRecorded(string $path, string $mimeType, ?string $id)
{
// Store or process the recording
$this->recordings[] = [
'path' => $path,
'mimeType' => $mimeType,
'id' => $id,
];
}
```

## Notes

- **Microphone Permission:** The first time your app requests microphone access, users will be prompted for permission. If denied, recording functions will fail silently.

- **File Format:** Recordings are stored as M4A/AAC audio files (`.m4a`). This format is optimized for small file sizes while maintaining quality.

- **Storage Location:**
- **Android:** Recordings are stored in the app's cache directory (`context.cacheDir/audio_{timestamp}.m4a`). These are temporary files and may be deleted by the system.
- **iOS:** Recordings are stored persistently in `~/Library/Application Support/Audio/NativePHP_{timestamp}.m4a` and are excluded from iCloud backup.

- **Recording State:** Only one recording can be active at a time. Calling `start()` while a recording is in progress will return `false`.

- **Auto-Start Behavior:** If you don't explicitly call `start()`, the recording will automatically start when the `PendingAudioRecorder` is destroyed. This maintains backward compatibility with earlier versions.
61 changes: 61 additions & 0 deletions resources/views/docs/mobile/2/apis/biometrics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Biometrics
order: 100
---

## Overview

The Biometrics API allows you to authenticate users using their device's biometric sensors like Face ID, Touch ID, or
fingerprint scanners.

```php
use Native\Mobile\Facades\Biometrics;
```

## Methods

### `prompt()`

Prompts the user for biometric authentication.

```php
use Native\Mobile\Facades\Biometrics;

Biometrics::prompt();
```

## Events

### `Completed`

Fired when biometric authentication completes (success or failure).

```php
use Livewire\Attributes\On;
use Native\Mobile\Events\Biometric\Completed;

#[On('native:'.Completed::class)]
public function handle(Completed $event)
{
if ($event->success) {
// User authenticated successfully
$this->unlockSecureFeature();
} else {
// Authentication failed
$this->showErrorMessage();
}
}
```

## Platform Support

- **iOS:** Face ID, Touch ID
- **Android:** Fingerprint, Face unlock, other biometric methods
- **Fallback:** System authentication (PIN, password, pattern)

## Security Notes

- Biometric authentication provides **convenience**, not absolute security
- Always combine with other authentication factors for sensitive operations
- Consider implementing session timeouts for unlocked states
- Users can potentially bypass biometrics if their device is compromised
Loading
Loading