Under the Hood

A technical look at SwiftMiner's internal architecture. Explore how we utilize native Swift concurrency, local SQLite engines, secure macOS keychains, and socket networking to build a high-performance desktop application.

SwiftMiner is engineered from the ground up as a native macOS application. Instead of relying on bloated browser frameworks or resource-intensive electron wrappers, it is built directly on Apple's developer frameworks to run in the background with negligible memory and CPU footprints.

System Architecture

The application is split into four shipping targets to maintain strict separation of concerns:

SwiftMiner Activity Log
The Activity Log surfaces the engine's real work — campaign scans, claim checks and cycle timings.
  • App UI (SwiftUI): Responsible for the native macOS layouts, including the multi-miner overview cards, real-time log consoles, and account settings panels.
  • SwiftMinerCore: The core daemon engine that manages token lifecycle operations, active drop tracking, automatic claiming intervals, and database synchronization.
  • SwiftMinerService: Houses the embedded HTTP daemon that parses incoming local LAN connections and enforces Twitch OAuth token validations. It also serves the Discord integration, including the device-code activation flow that links a Discord account to a miner.
  • SwiftMinerSafariExtension: An optional Safari web extension, SwiftMiner Query Hash Discovery, used to observe Twitch's current GraphQL query hashes. It is a fallback for when upstream hashes drift, and never runs unless you enable it.

Swift Concurrency Model

SwiftMiner relies heavily on modern Swift Concurrency (async/await, Actors, and Structured Concurrency) to orchestrate dozens of background activities simultaneously without freezing the user interface.

  • Actors for Thread Safety: To prevent data races, core subsystems like MinerEngine, KeychainTokenStore, and HTTPAPIServer are defined as Swift actors. This guarantees that all access to their internal state is isolated and processed sequentially across threads.
  • Structured Concurrency: The MinerManager supervises individual account miners using structured tasks. Each miner operates on its own task loop, executing polling cycles, stream switching, and claiming operations independently. If an account is removed or paused, its specific task tree is canceled cleanly.
  • Non-blocking UI: State changes (such as progress bars updating or new logs arriving) are funneled from background threads back to the Main Actor (UI thread) using reactive publishers. This ensures the SwiftUI layout re-renders smoothly.

Campaign Scheduling

Each miner decides for itself what to watch next, so one account's choices never block another's.

  • Strategies: MiningStrategy offers three modes — Smart, which works through everything eligible; Prefer prioritised games, which favours your list but falls back to the rest; and Only prioritised games, which mines nothing else.
  • Drop-aware ordering: The engine prefers campaigns that finish soonest and keeps partial progress rather than discarding it, so a nearly-complete drop is not abandoned for a fresher one.

API Clients & WebSockets

SwiftMiner connects directly to Twitch servers using optimized network clients with zero intermediary relays.

  • REST & GraphQL client: The core TwitchAPIClient interfaces with Twitch Helix API endpoints and GQL endpoints. Request batches are managed via URLSession utilizing HTTP/2 connection pooling to keep network overhead low.
  • WebSocket PubSub: To avoid aggressive API rate limits and retrieve progress changes instantly, PubSubClient establishes a persistent connection to Twitch's WebSocket-based PubSub system. This allows the app to listen for real-time claim triggers and progression events the moment they are recorded.
  • User-Agent Matching: To prevent API requests from being flagged or rejected by Twitch, the client requests generate custom headers matching typical desktop Safari/Chrome browsers.

SQLite Caching

To avoid hammering Twitch's servers on startup and keep history local, SwiftMiner integrates a local database layer.

  • Engine Details: SwiftMiner uses a local, lightweight SQLite instance managed via the SQLiteManager. It maintains tables for campaign details, active channels, claim records, and session data for the Web Dashboard.
  • Automatic Purging: Old campaign listings, telemetry data, and expired local Web Dashboard sessions are regularly purged automatically to prevent database bloat.

macOS System Integration

SwiftMiner relies on Apple's security APIs to secure your Twitch account details.

  • Keychain Services: Your Twitch OAuth tokens and client credentials are never saved in plain text database tables. Release builds write each account to your login Keychain through Apple's Keychain Services API as its own generic-password item, marked AfterFirstUnlockThisDeviceOnly so it is readable only on the Mac that stored it and never syncs anywhere.
  • No Cloud Relays: Unlike cloud-based services, SwiftMiner runs entirely on your Mac. Your private Twitch credentials never leave your machine and are only sent directly to Twitch APIs.
  • Signed, self-updating builds: Releases are signed and notarized by Apple, and the in-app updater is built on Sparkle. Each update is checked against its EdDSA signature before it is allowed to install, so a tampered download is rejected rather than run.

Custom Web Daemon

The Web Dashboard server is a masterpiece of zero-dependency native engineering.

  • Network.framework: Instead of pulling in massive server-side frameworks (like Vapor, Kitura, or Node.js), SwiftMiner implements HTTPAPIServer directly on top of Apple's low-level Network.framework. It acts as a lightweight TCP socket listener.
  • Performance: The server runs in-process with no separate daemon and no third-party dependencies to load. It parses standard HTTP/1.1 headers, decodes query parameters, and routes them to handler closures asynchronously.
  • Shared routing: The same listener serves the Discord integration. DiscordAPIRoutes and DiscordProjectionBuilder handle account linking and build the per-user views SwiftBot reads, so there is no second server to run or expose.