Native modules¶
Cross-platform wrappers around device APIs that are not part of the
view tree: camera, GPS, file I/O, notifications, clipboard, share
sheet, deep links, permissions, connectivity, secure storage, battery,
haptics, and biometrics. Each module is implemented twice (once per
platform) and dispatches at runtime based on the IS_ANDROID and
IS_IOS flags from pythonnative.utils, with a safe desktop fallback.
Both synchronous and coroutine APIs exist (chosen to match the
platform call). For the call-site patterns, the reactive
use_app_state / use_net_info hooks, and the runtime coroutines are
scheduled on, see the Native modules guide
and the Async + data guide.
Camera¶
Cross-platform camera and gallery access.
Both entry points are coroutines: await Camera.take_photo() returns
the saved image path (a str) or None if the user cancels.
Internally each call instantiates a fresh native delegate / activity
request and bridges its completion onto the PythonNative asyncio
runtime, so callers don't have to know whether the picker is backed by
UIImagePickerController (iOS) or
Intent(MediaStore.ACTION_IMAGE_CAPTURE) (Android).
Example
Classes:
| Name | Description |
|---|---|
Camera |
Camera and image-picker interface. |
Functions:
| Name | Description |
|---|---|
deliver_android_activity_result |
Forward an Activity result to the registered camera coroutine. |
Camera
¶
Camera and image-picker interface.
All methods are static coroutines. They dispatch to the iOS or Android implementation at call time based on the runtime platform.
Methods:
| Name | Description |
|---|---|
take_photo |
Launch the device camera to capture a photo. |
pick_from_gallery |
Open the system gallery picker. |
take_photo
async
staticmethod
¶
Launch the device camera to capture a photo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**options
|
Any
|
Reserved for platform-specific tuning. Currently
unused; future kwargs (e.g., |
{}
|
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The saved image path, or |
Optional[str]
|
no camera is available. |
pick_from_gallery
async
staticmethod
¶
deliver_android_activity_result
¶
Forward an Activity result to the registered camera coroutine.
The host Activity should call this from onActivityResult so
the pending
take_photo
/
pick_from_gallery
awaitable receives a path. Returns True if a Python callback
was invoked (so the host can short-circuit further handlers).
Location¶
Cross-platform location / GPS access.
Location.get_current
is a coroutine that resolves to a (latitude, longitude) tuple, or
None if no recent fix is available or the user denies permission.
Permission prompts are triggered the first time a location-using API
is called; ensure the appropriate manifest entries
(android.permission.ACCESS_FINE_LOCATION) and Info.plist keys
(NSLocationWhenInUseUsageDescription) are present.
Example
Classes:
| Name | Description |
|---|---|
Location |
GPS / location-services interface. |
Location
¶
GPS / location-services interface.
Methods:
| Name | Description |
|---|---|
get_current |
Request the device's current location. |
get_current
async
staticmethod
¶
File system¶
Cross-platform app-scoped file I/O.
Provides static helpers for reading, writing, and deleting files in the
app's sandboxed storage area. Relative paths are resolved against
FileSystem.app_dir;
absolute paths are used as-is.
Example
Classes:
| Name | Description |
|---|---|
FileSystem |
App-scoped file I/O. |
FileSystem
¶
App-scoped file I/O.
Every instance method operates on either an absolute path or a path
relative to
app_dir.
Errors are swallowed and reported as falsy return values (None
for readers, False for writers) so callers can treat the API as
best-effort.
Methods:
| Name | Description |
|---|---|
app_dir |
Return the app's writable data directory. |
read_text |
Read a text file. |
write_text |
Write a text file, creating parent directories as needed. |
exists |
Return whether a file or directory exists. |
delete |
Delete a single file. |
list_dir |
List the entries in a directory. |
read_bytes |
Read a binary file. |
write_bytes |
Write a binary file, creating parent directories as needed. |
get_size |
Return file size in bytes. |
ensure_dir |
Create a directory (and any missing parents) idempotently. |
join |
Join path components using the OS separator. |
app_dir
staticmethod
¶
app_dir() -> str
Return the app's writable data directory.
On Android the result is Context.getFilesDir(). On iOS it is
the user's Documents directory. On a desktop machine without
either runtime, a .pythonnative_data directory is created
under the user's home folder.
Returns:
| Type | Description |
|---|---|
str
|
Absolute path to the app's data directory. |
read_text
staticmethod
¶
write_text
staticmethod
¶
Write a text file, creating parent directories as needed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Absolute or |
required |
content
|
str
|
String to write. |
required |
encoding
|
str
|
Text encoding (default |
'utf-8'
|
Returns:
| Type | Description |
|---|---|
bool
|
|
exists
staticmethod
¶
delete
staticmethod
¶
list_dir
staticmethod
¶
read_bytes
staticmethod
¶
write_bytes
staticmethod
¶
get_size
staticmethod
¶
ensure_dir
staticmethod
¶
join
staticmethod
¶
Join path components using the OS separator.
Equivalent to os.path.join(*map(str, parts)). Provided as a
convenience so callers do not need to import os.path
directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*parts
|
Any
|
Path components (each coerced to |
()
|
Returns:
| Type | Description |
|---|---|
str
|
The joined path string. |
Notifications¶
Cross-platform local notifications.
Provides coroutines for requesting permission and scheduling /
cancelling local push notifications. Uses Android's
NotificationManager or iOS's UNUserNotificationCenter.
On iOS you must await Notifications.request_permission() before
scheduling. On Android 13+ the runtime permission should be requested
through standard Android APIs (the manifest declaration is otherwise
sufficient).
Example
Classes:
| Name | Description |
|---|---|
Notifications |
Local notification interface. |
Notifications
¶
Local notification interface.
Methods:
| Name | Description |
|---|---|
request_permission |
Request notification permission from the user. |
schedule |
Schedule a local notification. |
cancel |
Cancel a pending notification by its identifier. |
request_permission
async
staticmethod
¶
request_permission() -> bool
Request notification permission from the user.
On Android the manifest declaration is normally sufficient for
legacy permission grants and this returns True without
prompting (the runtime POST_NOTIFICATIONS prompt for Android
13+ should be requested via standard Android APIs).
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
otherwise. |
schedule
async
staticmethod
¶
schedule(title: str, body: str = '', *, delay_seconds: float = 0, identifier: str = 'default', **options: Any) -> bool
Schedule a local notification.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Notification title. |
required |
body
|
str
|
Notification body text. |
''
|
delay_seconds
|
float
|
Seconds from now until delivery. Use |
0
|
identifier
|
str
|
Stable ID used by
|
'default'
|
**options
|
Any
|
Reserved for future tuning (e.g., |
{}
|
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
call failed. |
Clipboard¶
Cross-platform clipboard access.
Clipboard reads and writes the system
pasteboard. All methods are synchronous: UIPasteboard (iOS) and
ClipboardManager (Android) both answer immediately, so there's no
need for a coroutine.
On a desktop machine (neither Android nor iOS) the module falls back to a process-local string buffer. That keeps it usable in the desktop mock target and unit tests instead of raising.
Example
Classes:
| Name | Description |
|---|---|
Clipboard |
System clipboard interface (synchronous). |
Clipboard
¶
System clipboard interface (synchronous).
Methods:
| Name | Description |
|---|---|
set_string |
Copy |
get_string |
Return the current clipboard string ( |
has_string |
Return |
Share¶
Present the system share sheet.
Share.share is a coroutine that opens
UIActivityViewController (iOS) or an ACTION_SEND chooser
(Android) and resolves to True once the user completes a share or
False if they dismiss it.
Example
Classes:
| Name | Description |
|---|---|
Share |
System share-sheet interface. |
Share
¶
System share-sheet interface.
Methods:
| Name | Description |
|---|---|
share |
Open the share sheet with |
share
async
staticmethod
¶
share(*, message: Optional[str] = None, url: Optional[str] = None, title: Optional[str] = None) -> bool
Open the share sheet with message / url.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
Optional[str]
|
Text body to share. |
None
|
url
|
Optional[str]
|
A URL to share (combined with |
None
|
title
|
Optional[str]
|
Chooser title (Android) / subject (iOS mail). |
None
|
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
cancelled or no share UI is available. |
Linking¶
Open URLs, deep links, and the system settings page.
Linking wraps UIApplication.openURL /
Intent(ACTION_VIEW) so a Python app can hand a URL (https:,
mailto:, tel:, a custom scheme, …) to the OS.
All methods are synchronous and return a bool describing whether
the platform accepted the request. On desktop they return False.
Example
Classes:
| Name | Description |
|---|---|
Linking |
System URL / deep-link interface (synchronous). |
Functions:
| Name | Description |
|---|---|
set_initial_url |
Record the launch URL (called by the native host on cold start). |
Linking
¶
System URL / deep-link interface (synchronous).
Methods:
| Name | Description |
|---|---|
open_url |
Hand |
can_open_url |
Return |
open_settings |
Open this app's entry in the system Settings app. |
get_initial_url |
Return the URL that launched the app, if any. |
Permissions¶
Runtime permission checks and requests.
Permissions normalizes the very different
iOS and Android permission models behind two calls:
check(permission)— synchronous, returns a status string without prompting.request(permission)— a coroutine that shows the system prompt (if needed) and resolves to the resulting status.
Statuses are "granted", "denied", "blocked" (denied with
"don't ask again" / Settings required), or "undetermined".
Supported permission names: "camera", "microphone",
"location", "photos", "notifications", "contacts".
Unknown names resolve to "undetermined".
Classes:
| Name | Description |
|---|---|
Permissions |
Runtime permission interface. |
Functions:
| Name | Description |
|---|---|
deliver_android_permission_result |
Forward an |
App state¶
Foreground / background app lifecycle state.
AppState exposes the current lifecycle phase
("active", "inactive", or "background") and lets you
subscribe to transitions. The native host (the iOS app delegate /
Android Activity) forwards lifecycle callbacks by calling
dispatch_app_state,
so the same listener machinery works on every platform and in tests.
Prefer the use_app_state hook inside
components; use the imperative API for non-UI code.
Example
Classes:
| Name | Description |
|---|---|
AppState |
App lifecycle state interface. |
Functions:
| Name | Description |
|---|---|
dispatch_app_state |
Update the current state and notify every listener. |
use_app_state |
Subscribe a component to |
AppState
¶
App lifecycle state interface.
Methods:
| Name | Description |
|---|---|
current_state |
Return the current lifecycle phase. |
add_listener |
Subscribe to lifecycle changes. |
dispatch_app_state
¶
Update the current state and notify every listener.
Called by the native host on lifecycle transitions. Unknown values are ignored so a misbehaving host can't push garbage into the tree.
Network connectivity¶
Network connectivity state.
NetInfo reports whether the device is online
and over what kind of connection. fetch returns a snapshot dict;
add_listener (and the use_net_info
hook) deliver live updates as the native host forwards connectivity
changes through
dispatch_net_info.
A snapshot looks like::
{"is_connected": True, "type": "wifi", "is_internet_reachable": True}
type is one of "wifi", "cellular", "ethernet",
"none", or "unknown".
Classes:
| Name | Description |
|---|---|
NetInfo |
Network connectivity interface. |
Functions:
| Name | Description |
|---|---|
dispatch_net_info |
Push a new connectivity snapshot and notify listeners. |
use_net_info |
Subscribe a component to |
NetInfo
¶
Network connectivity interface.
Methods:
| Name | Description |
|---|---|
fetch |
Return a fresh snapshot of connectivity state. |
add_listener |
Subscribe to connectivity changes; returns an unsubscribe fn. |
dispatch_net_info
¶
Push a new connectivity snapshot and notify listeners.
Secure storage¶
Encrypted key/value storage for secrets (tokens, credentials).
SecureStore persists small string values
in the iOS Keychain and Android EncryptedSharedPreferences — the
right place for auth tokens and other secrets that
AsyncStorage (plain, unencrypted) should
never hold.
All methods are synchronous and return a bool (writes/deletes) or
Optional[str] (reads). On desktop the module falls back to an
in-process dict so code paths stay exercisable without a device
Keychain.
Example
Classes:
| Name | Description |
|---|---|
SecureStore |
Encrypted secret storage (synchronous). |
SecureStore
¶
Encrypted secret storage (synchronous).
Methods:
| Name | Description |
|---|---|
set_item |
Store |
get_item |
Return the value for |
delete_item |
Delete |
Battery¶
Battery level and charging state.
Battery reports the current charge fraction
(0.0–1.0, or -1.0 when unknown) and charging state, and
lets you subscribe to changes that the native host forwards via
dispatch_battery.
Classes:
| Name | Description |
|---|---|
Battery |
Battery interface (synchronous getters + change listener). |
Functions:
| Name | Description |
|---|---|
dispatch_battery |
Notify listeners of a battery change (called by the native host). |
Battery
¶
Battery interface (synchronous getters + change listener).
Methods:
| Name | Description |
|---|---|
get_level |
Return the charge fraction in |
get_state |
Return |
add_listener |
Subscribe to battery changes; returns an unsubscribe fn. |
Haptics & vibration¶
Haptic feedback and raw vibration.
Two interfaces live here:
Haptics— semantic, iOS-style feedback (impact / notification / selection) backed byUIFeedbackGeneratoron iOS andVibrationEffectpatterns on Android.Vibration— a blunt "buzz for N milliseconds" interface for cases where you want an explicit duration.
Every method is synchronous and best-effort: on a device that lacks a Taptic Engine / vibrator, or on desktop, calls are silent no-ops rather than errors.
Classes:
| Name | Description |
|---|---|
Haptics |
Semantic haptic feedback (synchronous, best-effort). |
Vibration |
Raw vibration control (synchronous, best-effort). |
Haptics
¶
Semantic haptic feedback (synchronous, best-effort).
Methods:
| Name | Description |
|---|---|
impact |
Play a physical "impact" tap of the given |
notification |
Play a success / warning / error notification pattern. |
selection |
Play the light "selection changed" tick. |
Biometrics¶
Biometric authentication (Face ID / Touch ID / fingerprint).
Biometrics gates an action behind the
device's biometric hardware via LAContext (iOS) and
BiometricPrompt (Android).
is_available is synchronous; authenticate is a coroutine that
presents the system prompt and resolves to True on success or
False on failure / cancellation.
Example
Classes:
| Name | Description |
|---|---|
Biometrics |
Biometric authentication interface. |
Biometrics
¶
Biometric authentication interface.
Methods:
| Name | Description |
|---|---|
is_available |
Return |
authenticate |
Present the biometric prompt; resolve |
Next steps¶
- See guidance and permission setup in Native modules guide.