Part 12 · Best practices

Android Activity and iOS app lifecycle are not interchangeable

Prerequisites: 04-platform-ownership, 08-expo-dsl

Platform lifecycle forks

The same public result is backed by distinct native lifecycle signals. Nodes: JS request, Android, iOS, Terminal result.
The same public result is backed by distinct native lifecycle signals. [S12] [S16] [S17]

Request state machine

A conceptual single-settlement contract; platform SDK callbacks and ownership determine implementation. Nodes: Idle, Pending, Completed, Cancelled.
A conceptual single-settlement contract; platform SDK callbacks and ownership determine implementation. [S12] [S16]

Mental model verified

Expo’s hooks distinguish iOS app foreground/background from Android Activity foreground/background/destruction. Android coroutines can be tied to lifecycle scopes; UIKit work uses main-thread APIs, and Swift MainActor can express UI isolation.

[S12] [S16] [S17] [S18]

Worked flow synthesis

A biometric prompt begins, then the app backgrounds. On Android, handle Activity lifecycle and a cancelled or deferred result; on iOS, handle app state and SDK callback. Both paths should settle or explicitly cancel the JS request once, with a stable result shape.

[S12] [S16] [S17]

Engineering decision synthesis

Model pending, completed and cancelled states; clean up native listeners and avoid retaining stale view or Activity references. Test denial, background, process death and app relaunch as relevant.

[S12] [S16] [S18]

Failure mode and improvement synthesis

A pending Promise that never resolves after dismissal is a UX and resource bug. Track request IDs and terminal states; verify each path settles exactly once.

[S12] [S16]
Keep this: Expose a common JS result but respect different native lifecycle and permission paths.
Check yourself: Can a module assume an Activity that launched a request still exists when it returns?

No. The Activity may pause, be destroyed or be recreated; the module must handle missing owners and cancellation.

Sources & further reading

  1. [S12] Module API Reference

    Expo · official documentation or maintainer source · accessed 2026-10-09 · current documentation as accessed; examples conceptual

    Supports: Function, AsyncFunction, queues, views, events and lifecycle.

    Inspect the implementation boundary described by this source.

  2. [S16] Use Kotlin coroutines with lifecycle-aware components

    Android Developers · official documentation or maintainer source · accessed 2026-10-09 · current documentation as accessed; examples conceptual

    Supports: Activity lifecycle scopes and cancellation.

    Inspect the implementation boundary described by this source.

  3. [S17] UIKit

    Apple Developer · official documentation or maintainer source · accessed 2026-10-09 · current documentation as accessed; examples conceptual

    Supports: UIKit objects are normally used from the main thread.

    Inspect the implementation boundary described by this source.

  4. [S18] MainActor

    Apple Developer · official documentation or maintainer source · accessed 2026-10-09 · current documentation as accessed; examples conceptual

    Supports: Swift main actor execution contract.

    Inspect the implementation boundary described by this source.