Prove native behavior before choosing a mobile stack
A mobile stack should be chosen after the hardest native behavior has survived a physical device, not before. Cameras, sensors, background execution and permission flows are governed by operating systems, hardware and release policies that architecture diagrams cannot settle. A thin proof turns those unknowns into observable constraints while changing direction is still inexpensive.
Start with the capability that could break the product
Do not begin by reproducing the home screen or navigation. Identify the capability whose failure would force a product change: capturing a document in poor light, recording motion while the screen is locked, uploading media after the app leaves the foreground, or recovering when a permission is denied.
Write one claim that a device can disprove. For example: “After a user records a two-minute video, the upload resumes without reopening the app.” Then define the conditions: supported operating-system versions, minimum hardware, network loss, battery-saving mode and the maximum acceptable interruption.
This framing separates three questions that teams often collapse into “Can the framework do it?” The operating system may prohibit the behavior. A framework may expose it only through a native module. The behavior may work technically but create an unacceptable permission or review experience. Each answer leads to a different product decision.
Keep the proof thin but end to end
The proof needs the smallest real journey that crosses every uncertain boundary. Use a plain screen, temporary local storage and a disposable endpoint if necessary, but include the actual permission request, hardware API, app lifecycle transition and signed build.
For a camera-and-upload feature, that means opening the real camera, capturing representative media, saving it, starting transfer, backgrounding or terminating the app, changing connectivity and checking recovery. For motion or location, verify sampling while moving, after screen lock and after the operating system has reclaimed the process. Simulators are useful for repeatable UI work, but they do not reproduce camera optics, thermal pressure, radio changes, manufacturer power policies or a person’s response to permission prompts.
Run the proof on at least one supported iPhone and one representative Android device when both platforms are in scope. Add older or constrained hardware when the product requirement makes it relevant. The goal is not broad device certification; it is to expose whether the capability depends on a particular operating-system version, device class or vendor behavior.
Test states rather than the happy path
A single successful run proves very little. Use a compact state matrix whose rows are the moments that can change system behavior: first launch, permission granted, permission denied, permission revoked in settings, app foregrounded, app backgrounded, screen locked, process killed, network lost and device restarted.
Record observations, not just pass or fail. Note whether work continued, paused, restarted, duplicated or lost data. Capture the system prompt shown, the settings route needed for recovery and any visible notification or status indicator. Timestamped device logs and a short screen recording make disagreements easier to resolve.
Background behavior deserves special care because it is scheduled, not owned, by the application. Apple’s guide to choosing a background strategy distinguishes short completion work, deferred processing, transfers and event-driven wakes; the system controls when some of these opportunities occur. Android likewise documents system restrictions on background tasks, including user and device-manufacturer restrictions. A proof should therefore test delayed execution and recovery, not promise an exact timer that the platform does not guarantee.
Turn permission behavior into product behavior
Permission handling is part of the feature, not a setup chore. Ask at the point where the benefit is visible, explain what action requires access and give the user a useful route when access is refused. The proof should cover “not yet asked,” “allowed,” “denied” and “later revoked” as distinct states.
Test partial capability too. Can a user choose an existing photo when camera access is unavailable? Can a workout be entered manually when sensor data cannot be read? Can an upload wait safely for the foreground? These alternatives may remove the need for a more invasive permission or prevent one denied request from blocking the entire journey.
The result should be a decision table connecting each system state to a product response. That table is more valuable than a wrapper API demo because it defines copy, settings guidance, retry rules and data-loss protection before production architecture hardens around optimistic assumptions.
Let evidence choose the implementation boundary
Only after the proof should the team compare stacks. If the risky behavior works through a maintained cross-platform interface, has acceptable diagnostics and requires little platform-specific lifecycle code, a shared implementation may be sensible. If success depends on low-level camera control, precise sensor processing, platform-specific background modes or rapid access to new operating-system APIs, native ownership may reduce uncertainty.
The choice is not necessarily all-native or all-shared. Keep ordinary flows shared while isolating one capability behind a small native boundary, or use separate platform implementations for the critical service while preserving a common product contract. Estimate the code that must differ, who can maintain it, how it will be tested after OS updates and how failure surfaces to the rest of the app.
This is how Alfcode’s mobile delivery practice can apply React Native, Swift and Kotlin without treating any one of them as a default answer. SwiftUI and Jetpack Compose are also available for native interface work, but the physical-device proof determines where native code is necessary and where sharing earns its place. Alfcode’s stated store-submission practice belongs in the same decision: signing, entitlements, privacy declarations and review-sensitive behavior should be exercised in a release-shaped build, not postponed until launch week.
Finish with a decision record
End the proof with a short record containing the capability claim, tested devices and OS versions, state matrix, observed limits, fallback behavior, release prerequisites and unresolved risks. Attach enough evidence for another engineer to repeat the run. Then state the stack consequence plainly: shared implementation is sufficient, a native module is required, separate native implementations are warranted, or the product behavior must change.
Before approving a mobile stack, ask one final testable question: has the riskiest capability completed its real journey on a physical device after permission denial, backgrounding, process termination and network loss? If not, the team is selecting a stack while its most consequential constraint is still unknown.
Have a product decision to make?
Tell us what you are building. We will help turn the hard parts into a clear plan.
Keep reading.
Human handoff deserves a first-class product state
Escalation works when context, ownership, expectations, and re-entry are designed together, so users remain inside one continuous workflow.
Read
Treat every notification as a spend from attention
Useful notifications earn interruption through urgency, timing, channel choice, quiet delivery, and controls that preserve the user’s attention.
Read