← Back to Mobile application starters · project planning pack
See how it helps
Mobile state and APIs
Separates mobile interface, server and persistent state while making requests resilient to races and authentication changes.
mobile-state-api
Agents using this skill
When is it useful?
Use when stale responses overwrite newer screen state or retries duplicate writes.
What does it help you do?
- Assigns state to appropriate memory, cache or persistent storage.
- Handles cancellation, overlapping requests and repeat-safe mutations.
- Keeps credentials and authorization at appropriate security boundaries.
Try asking this
Fix search results arriving out of order and preserve an unsent edit through a token refresh. Expire the token during editing and return search responses backwards. Refresh authentication once, retain the draft and display only the latest query's results.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Mobile State & API Integration
Keep presentation, application state, business logic and API communication cleanly separated, with one explicit source of truth and persistence tier for every piece of data.
1. Partition state by ownership and storage tier
- Server state (entities, paginated feeds, remote config): manage through the project's query/repository layer (TanStack Query, Riverpod
AsyncNotifier, Bloc + Repository) with explicitstaleTime, cache invalidation and focus/reconnect refetching—never mirror server entities manually into a second global store. - Hardware-backed encrypted storage: store access tokens, refresh tokens and session secrets exclusively in iOS Keychain / Android Keystore (
expo-secure-storewithWHEN_UNLOCKED_THIS_DEVICE_ONLYorAFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY,react-native-keychain,flutter_secure_storage)—never in plainAsyncStorage,MMKV,SharedPreferencesorUserDefaults. - Structured local persistence: store non-sensitive preferences, feature flags and user drafts in the repo's local store (
expo-sqlite,MMKV,Drift,SharedPreferences), and wipe all user-scoped caches, DB tables and drafts on sign-out. - Ephemeral UI state (open sheets, filter text, active tab): keep local to the screen or component.
2. Resilient API integration, concurrency and write safety
- Align request payloads, cursor pagination, field-level
422validation errors and error codes with the backend developers; normalize transport errors into typed domain errors at the client boundary. - Cancel or ignore stale responses: pass
AbortSignal/CancelTokento in-flight fetches and guard post-awaitstate updates (context.mountedin Flutter, cancellation tokens in hooks/notifiers) so rapid filter changes or screen unmounts never overwrite newer state. - Duplicate write prevention: disable submit triggers while a mutation is in flight (
isPending), attach anIdempotency-Keyheader (client UUID) to state-changing requests (POST/PATCH), and never blindly auto-retry a non-idempotent mutation when a socket drops after the request was sent. - Optimistic updates: snapshot previous cache state before mutating, roll back on error with user feedback, and reconcile with the server's canonical response.
3. Mobile client security boundaries
- Treat the mobile binary and JS bundle (
EXPO_PUBLIC_*,--dart-define) as public: never embed private API keys, service-role credentials or signing secrets in client code. - Never treat client-side role flags or local biometric prompts as authorization; the backend must enforce permissions on every request.
- Redact tokens, passwords and PII from console logs, crash breadcrumbs and network inspectors.
Before you finish
- Server cache, encrypted Keychain/Keystore, local persistence and ephemeral UI state are cleanly separated.
- Tokens live in encrypted storage; sign-out wipes tokens, query caches and user-scoped local data.
- In-flight requests handle cancellation/unmount; mutations guard against double taps and use idempotency keys.
- Optimistic updates have rollback; zero private secrets or unredacted tokens appear in bundle or logs.
Included files 2
LICENSE.txtSKILL.md
