Build networking features from HTTP fundamentals through real application lifecycles. The topics move from what URLSession puts on the wire, through client design, authentication, and resilience, to transfers, live connections, testing, and diagnosis. Each article measures the behavior it describes and ends with an exercise.
The examples use Swift 6 language mode and were compiled and run with the Swift 6.4 toolchain from Xcode 27.1 on macOS 26. Most of them talk to LocalServer, a small HTTP/1.1 server on the loopback interface whose source is in the appendix of the first article, so that every claim about redirects, retries, caching, timeouts, and streaming is checked against real requests. The testing articles are Swift packages run with swift test, and the iOS-only code in the background transfers article was compiled against the iOS 26 SDK.
Diagrams show request sequences, state machines, and timelines; equations appear where they give a precise answer, such as how many connections a burst needs, how much jitter flattens a retry storm, or how many requests coalescing saves. The concurrency roadmap covers the language features these articles rely on.
Article available Coming soon
1. HTTP and URL Loading
HTTP Methods, Status Codes, and Headers: What URLSession Puts on the Wire
Most networking bugs in apps are not caused by a broken network. They come from a client and a server that disagree...
URLs, Query Parameters, and Percent Encoding in Swift
A URL looks like a string, and that is the root of most URL bugs. Building one with string interpolation works for...
Choosing a URLSession Configuration
URLSession.shared is the first networking API most Swift developers meet, and for a quick request it is the right one. For an...
Requests and Responses with async and await in URLSession
Before Swift concurrency, a network request was a callback that arrived on an unknown queue, at some point, maybe more than once...
Separating Transport Errors from Application Failures
“Something went wrong. Please try again.” is what an app says when its networking layer has collapsed every failure into one case....
2. Designing a Client
Building Typed Endpoints and Request Bodies in Swift
A networking layer built from URLRequest values scattered across view models has the same bug in twenty places. One call site forgets...
Decoding JSON with Codable: Keys, Numbers, Dates, and Failure
Codable makes the happy path almost free: declare a struct whose property names match the JSON, call JSONDecoder().decode, and it works. The...
Validating Decoded Data Before It Reaches the UI
A response that decodes is not a response that is correct. JSONDecoder checks that a title is a string; it does not...
Pagination: Page Numbers, Cursors, and Stable Ordering
An infinite list in an app is a sequence of requests pretending to be one list. Each request returns a page, and...
Designing an API Client Around Consumer Needs
Most API clients are designed from the server inward. Someone opens the API documentation, writes one method per endpoint, returns whatever the...
3. Authentication and Trust
Authentication Headers and Credential Scope
A credential is only as safe as the set of requests it is attached to. An access token that the app sends...
Refreshing Credentials Without Duplicate Requests
Access tokens expire on purpose. A short lifetime limits what a leaked token is worth, and the app holds a longer-lived refresh...
App Transport Security and TLS Trust
HTTPS promises three things: nobody on the path can read the traffic, nobody can change it undetected, and the server at the...
Handling Logout During an In-Flight Request
Logging out looks like the simplest feature in an app: delete the token, show the sign-in screen. The bugs live in everything...
Redacting Sensitive Data from Network Logs
Network logs are the most useful diagnostic an app has and one of the easiest ways for it to leak what it...
4. Resilience and Freshness
Timeouts, Cancellation, and Request Lifetimes
Every request ends in one of three ways: it completes, it fails, or somebody stops waiting for it. The third way is...
Retry Policies, Backoff, and Idempotency
Retrying a failed request is the cheapest reliability improvement a client can make, and one of the easiest ways for a client...
HTTP Caching with Cache-Control and ETag
The fastest request is one that is never sent, and the second fastest is one whose answer is “nothing changed.” HTTP has...
Offline Behavior and Reachability Assumptions
“Check whether the network is reachable before making a request” is one of the most persistent pieces of networking advice, and one...
Coalescing Duplicate Requests and Rejecting Stale Results
Apps send the same request many times without meaning to. Thirty table cells each ask for the same author’s avatar. A detail...
5. Transfers and Live Connections
Uploading Files and Multipart Form Data
Uploading a file looks like a request with a large body, and for small files that is all it is. The details...
Download Progress, Resuming, and Temporary Files
A large download has three needs that a small request does not. The user wants to see it progress. It must survive...
Background Transfers and App Relaunch
An iOS app gets a few seconds of execution after the user leaves it, and then it is suspended. A 600 MB...
WebSockets: Connection State and Reconnection
An HTTP request has a beginning and an end, and the client always knows which of the two it is waiting for....
Streaming Responses and Incremental Parsing
Most responses are read whole: wait for the last byte, then decode. Some responses are worth reading while they arrive. A search...
6. Testing and Observability
Isolating HTTP Fixtures with URLProtocol
A test that talks to a real server is slow, depends on the network and the server’s data, and cannot easily produce...
Testing Status Codes, Invalid Payloads, and Transport Errors
The happy path of a networking client gets tested by accident: every developer runs it a hundred times a day. The failure...
Verifying Contracts Against a Controlled Server
Unit tests with stubbed responses prove that a client handles the responses its authors wrote down. They cannot prove that the server...
Reading URLSessionTaskMetrics
“The request is slow” is not a diagnosis. A request can be slow because the name took long to resolve, because the...
Diagnosing Slow Requests and Excessive Network Usage
Two complaints reach every app team eventually: “the screen takes forever to load” and “the app uses a lot of data.” Both...
Up next
Persistence