-
Notifications
You must be signed in to change notification settings - Fork 1
Platform Notes Thread Safety and Performance
Husnain Ali edited this page Sep 27, 2026
·
3 revisions
-
NetworkClientisSendable. Construct one and share it. - Shared mutable state lives in actors:
TokenManager,RequestQueue,RequestRegistry,RequestDeduplicator, the cache stores,InMemoryMetrics,OfflineRequestQueue. - The concurrent 401 case is handled by
TokenManager's single-flight refresh; there is an explicit deadlock test for "full queue plus expired token". - The only
@unchecked Sendabletypes are the threeURLSessiondelegate shims (whose callbacks are notasync) and the test doubles; each guards a few lines with a lock and a comment. - SwiftUI
NetworkResource/Pagedare@MainActor. - The whole test suite runs green under ThreadSanitizer in CI.
-
URLSessionconnection reuse is preserved (one session per client, plus a dedicated session per upload/download for progress delegation). -
maxConcurrentRequests(default 6, matching theURLSessionper-host limit) bounds in-flight work; extra requests queue byEndpoint.priority. - Deduplication removes redundant identical GETs. See Request Management.
- The cache short-circuits the network entirely for fresh
cacheFirst/cacheOnlyhits. See Caching. - Large multipart parts and downloads stream from and to disk rather than loading into memory.
- Retry timing is computed, not busy-waited (
NetworkClock), and theRetry-Afterdate parser reuses one formatter instead of allocating one per request.
Apple-platform behaviors that shape the design or that you should be aware of:
| Area | Note |
|---|---|
| Upload/download progress | The async URLSession.upload(for:from:) / download(for:) methods do not reliably forward didSendBodyData / didWriteData to a per-task delegate. SwiftNetworkKit works around this by running each transfer on a dedicated URLSession with a session-level delegate (TransportSessionDelegate). A side effect: uploads and downloads do not share the main client's connection pool, and a delegate, credential handler, or pinning attached directly to a caller-supplied URLSession does not apply to them. |
| Background transfers |
URLSessionConfiguration.background requires app-side wiring (an AppDelegate completion handler, an app-wide session identifier). SwiftNetworkKit does not configure background sessions automatically; download(_:to:) runs in-process. |
| Background sessions in the Simulator | Historically flaky (rdar://26870455). Test background behavior on a device. |
| Keychain on macOS CI |
KeychainTokenStorage can be unavailable on headless CI runners with no keychain. KeychainTokenStorage.isAvailable guards this; the test suite skips those cases when it returns false. |
URLProtocol + request bodies |
Custom URLProtocol subclasses (used by URLProtocolStub in tests) historically mishandle httpBodyStream (rdar://26849668). The stub asserts on URL, method, and headers rather than replaying streamed bodies. |
| TLS 1.3 0-RTT | Not used. URLSession decides; the package does not opt into early data. |
visionOS / watchOS / tvOS
|
CI builds the library for every declared Apple platform, and runs the full test suite on iOS, macOS, and Linux (Foundation subset). tvOS / watchOS / visionOS are "builds green, test suite not run on-device". |
If you hit a platform bug not listed here, please file an issue with the OS version and a minimal reproduction.
SwiftNetworkKit is source-available proprietary software (not open source). See FAQ Licensing and Support. Repo: https://github.com/ihusnainalii/SwiftNetworkKit · Docs: https://swiftnetworkkit.vercel.app/
Getting started
Guides
- Defining Endpoints
- Authentication and Token Refresh
- Security and Certificate Pinning
- Retry Policy
- Interceptors
- Request Management
- Caching
- Offline Request Queue
- Uploads Downloads and Progress
- Pagination and Batch
- Combine and SwiftUI
- Error Handling
- Observability
- Testing and Mocking
- Best Practices and a Complete Example
- Platform Notes, Thread Safety and Performance
Reference