← Back to Mobile app developers

Skill · Version 1.0.0

Mobile state and APIs

Separates mobile interface, server and persistent state while making requests resilient to races and authentication changes.

mobile-state-api

Team members using this skill

See how it helps

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.

Details…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 explicit staleTime, 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-store with WHEN_UNLOCKED_THIS_DEVICE_ONLY or AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY, react-native-keychain, flutter_secure_storage)—never in plain AsyncStorage, MMKV, SharedPreferences or UserDefaults.
  • 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 422 validation 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 / CancelToken to in-flight fetches and guard post-await state updates (context.mounted in 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 an Idempotency-Key header (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.txt
  • SKILL.md