Mobile Development · Guide

Networking & Offline

Consuming APIs on a connection that comes and goes, and designing for offline as the normal case rather than the error case.

— min read Mobile Development

The Network Is Not There

On a desktop the network is usually up. On a phone it is a lift, a tunnel, a train, a hotel captive portal and a 2-bar connection that resolves DNS in four seconds. Treat loss of connectivity as a normal state, not an error.

That single assumption changes the design. Requests need timeouts and retries, responses need caching, writes need queueing, and the interface needs something honest to show while none of it has arrived.

Consuming REST APIs

Every platform has a settled stack — Retrofit with OkHttp and a JSON serializer on Android, URLSession with Codable on iOS. The library is not the interesting part; the policy around it is.

PolicySensible default
Connect timeout~10s — a hung socket is worse than a fast failure
RetriesIdempotent requests only, with exponential backoff and jitter
Auth refreshOne place, deduplicated — not per call site
ErrorsTyped: network, HTTP status, decoding. They need different messages
PayloadsAsk for what the screen needs; mobile data is the user's money
Never retry a non-idempotent request blindly. A payment that timed out may well have succeeded — retrying charges twice. Use an idempotency key or do not retry.

Decode into your own models rather than passing API shapes into the UI. An extra mapping layer sounds like ceremony until the backend renames a field and the change is contained in one file.

Offline-First & Sync

Offline-first inverts the usual flow: the local database is the source of truth for the UI. Screens read from it and always have something to show; the network's job is to update the database in the background, and connectivity becomes a detail rather than a blocking condition.

PieceJob
Local storeWhat the UI reads, always available
Sync workerPulls updates and pushes queued changes when possible
OutboxLocal writes waiting to reach the server, with retry
Conflict ruleWhat happens when both sides changed the same thing

Conflicts are the hard part and they need a decision, not a default. Last-write-wins is simple and silently destroys work. Server-wins is predictable and frustrating. Merging per field is better where the data allows it, and for anything the user typed, asking is usually kinder than guessing.

Optimistic updates make an app feel instant: apply the change locally, sync in the background. The obligation is to handle rejection visibly — a change that silently reverts twenty seconds later is worse than a spinner.

Interview Questions

What does offline-first mean in practice?

The local database is the source of truth for the UI. Screens read from it and always render, while a background worker syncs changes both ways. Connectivity stops being a precondition for the app working.

Why is blind retry dangerous?

Non-idempotent requests may have succeeded before the timeout. Retrying a payment or a create can duplicate it — retry only idempotent calls, or send an idempotency key.

How do you resolve sync conflicts?

It is a product decision. Last-write-wins is simple but destroys work, server-wins is predictable but frustrating, field-level merge is better where possible, and user-authored content usually deserves a prompt.

Why map API responses into your own models?

It contains change. If the backend renames or reshapes a field, only the mapping layer moves; the UI and business logic keep their stable types.

What is an outbox?

A local queue of writes made while offline, retried until the server accepts them. It is what lets the user keep working without a connection and without losing anything.

What is the risk with optimistic updates?

The server may reject the change after the UI has already shown it. Unless rejection is surfaced clearly, the user sees their action silently undone later and stops trusting the app.

Quick Quiz

1. In an offline-first app, the UI reads from…
2. You should retry automatically only when the request is…
3. Last-write-wins conflict resolution…
4. An outbox holds…
5. Optimistic updates require you to…