Skip to content
Husnain Ali edited this page Sep 27, 2026 · 2 revisions

SwiftNetworkKit

A modern, composable, protocol-oriented networking framework for Apple platforms.

Zero external dependencies · Swift 6 strict concurrency · 13 isolated actors · Single-flight 401 token refresh · SPKI SSL pinning

Why it exists

SwiftNetworkKit is a reusable client networking layer you drop into an app instead of hand-rolling URLSession plumbing per project. It exists because every app re-implements the same things badly: token refresh races, retry with backoff, certificate pinning, request cancellation, response caching, redacted logging, and a test seam.

What it solves

  • One typed Endpoint per API operation, decoded straight into your model.
  • A single NetworkError at the public boundary; every URLError, DecodingError, keychain OSStatus, and trust failure is mapped into it.
  • A TokenManager actor that handles concurrent 401s with a single-flight refresh and request queueing, so ten simultaneous requests trigger exactly one refresh.
  • Drop-in certificate pinning where the app ships a .cer and writes one line; the package owns the URLSession delegate.
  • A test double (MockNetworkTransport) that ships in the library, so consumers never touch the network in unit tests.

Who should use it: app teams that want a consistent networking layer across projects, and anyone who needs pinning, OAuth, offline queueing, or automatic refresh without pulling in a large framework.

Design principles

  1. Zero dependencies. Foundation, and platform frameworks behind #if canImport.
  2. Composed, not a god object. NetworkClient wires together small components (RequestBuilder, TokenManager, InterceptorChain, RequestQueue, caches, transport).
  3. Protocol-oriented. Every collaborator is a protocol with a real adapter and a test double.
  4. Modern Swift. ~95% async/await and actors under Swift 6 strict concurrency; Combine and SwiftUI are optional #if canImport adapters.
  5. Everything is configuration. No hardcoded URLs, timeouts, or pins in the package.

Get started

Guides

Topic Page
Defining endpoints, request/response shape Defining Endpoints
Auth strategies, token storage, automatic refresh, OAuth 2.0 Authentication and Token Refresh
Certificate and public-key pinning, security posture Security and Certificate Pinning
Retry, backoff, jitter, Retry-After Retry Policy
Request/response interceptors Interceptors
Cancellation, deduplication, reachability, concurrency Request Management
HTTP response caching Caching
Persisted offline replay queue Offline Request Queue
Multipart upload, file download, progress Uploads Downloads and Progress
Pagination and parallel batch requests Pagination and Batch
Combine publishers and SwiftUI helpers Combine and SwiftUI
The NetworkError model Error Handling
Environments, logging, metrics, tracing Observability
Mock transport and other test doubles Testing and Mocking
Recommended patterns + a full login-to-API example Best Practices and a Complete Example
Known platform quirks, thread safety, performance notes Platform Notes Thread Safety and Performance
Common questions, licensing, where to get support FAQ Licensing and Support
Semantic versioning and the roadmap Versioning and Roadmap

Demos

  • CLI tour (Sources/NetworkKitDemo/): a scripted run through every feature against the public jsonplaceholder.typicode.com API. swift run NetworkKitDemo
  • SwiftUI app (Examples/SwiftUIDemo/): a standalone iOS app with a searchable paginated user list, a POST form, an image downloader with a live progress bar, and a Diagnostics screen with two narrated walkthroughs (401 → refresh → retry, and an account-switch showing cache isolation).

Reporting an issue or asking a question

Open a GitHub Discussion for questions, or a GitHub Issue for a bug, with your OS/Xcode versions and a minimal reproduction. Report a security vulnerability privately per SECURITY.md, never in a public issue.

Clone this wiki locally