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.