Overview
SeeleSeek is a native macOS SwiftUI application written in Swift 6. The codebase is organized around three main concerns:- App-level state — a single
AppStateobject injected via SwiftUI environment that owns all feature states and the network client. - Networking — a layered stack (server connection → peer connections → protocol parsing) coordinated by
NetworkClient. - Features — self-contained modules under
Features/, each with observable state and aViews/subdirectory.
ServerConnection, PeerConnection, DatabaseManager) to isolate mutable state.
Directory Structure
App Entry Point
SeeleSeekApp creates a single AppState instance at launch, registers it with AppDependencyManager (for App Intents), and injects it into the view hierarchy via a custom environment key.
appState.configure() wires up the NetworkClient callbacks to all feature states and initializes the database.
State Management
SeeleSeek uses Swift 6@Observable classes throughout, replacing ObservableObject/@Published.
@Observable classes
Feature states (e.g.
SearchState, TransferState) are @Observable classes marked @MainActor. SwiftUI tracks property reads automatically without @Published.@MainActor for UI
All state that drives UI is isolated to
@MainActor. Updates from background actors are dispatched with await MainActor.run { } or by calling @MainActor-isolated methods.NetworkClient itself is @Observable @MainActor. Its properties (connection status, distributed network info) can be read directly in SwiftUI views.Networking Layer
NetworkClient
NetworkClient (Core/Network/NetworkClient.swift) is the central coordinator. It owns:
- A
ServerConnectionfor the Soulseek server TCP socket. - A
PeerConnectionPoolmanaging all active peer connections. - A
ServerMessageHandlerthat dispatches parsed server messages to callbacks.
NetworkClient during appState.configure(). For example, SearchState sets networkClient.onSearchResults to receive incoming search results.
ServerConnection
Anactor (Core/Network/Connections/ServerConnection.swift) wrapping NWConnection to the Soulseek server (server.slsknet.org:2242). It:
- Buffers incoming TCP bytes and yields complete framed messages to an
AsyncStream<Data>. - Enables TCP keepalive (probe every 60 s, give up after 3 missed probes) to detect silent connection loss.
- Implements exponential backoff reconnect (5 s → 10 s → 30 s → 60 s cap) in
NetworkClient.
PeerConnection and PeerConnectionPool
PeerConnection (Core/Network/Connections/PeerConnection.swift) is an actor managing a single peer TCP socket. It handles:
- Connection types:
P(peer messages),F(file transfer),D(distributed network). - Incoming and outgoing handshake (
PeerInit/PierceFirewall). - Per-token
TransferRequesthandlers to support concurrent downloads on a single connection. - SeeleSeek-extension messages (codes 10000+) for capability handshake and album artwork requests.
PeerConnectionPool tracks all active PeerConnection instances and routes incoming events up to NetworkClient callbacks.
Protocol Layer
| File | Responsibility |
|---|---|
MessageCode.swift | Enums for server (ServerMessageCode), peer (PeerMessageCode), distributed (DistributedMessageCode), and SeeleSeek-extension (SeeleSeekPeerCode) message codes |
MessageBuilder.swift | Static methods that serialize each message type into Data with the correct length-prefixed framing |
MessageParser.swift | Parses framed Data into typed message structs |
Database Layer
DatabaseManager (Database/DatabaseManager.swift) is a singleton actor backed by a GRDB DatabasePool in WAL mode. It runs versioned migrations and exposes generic read / write methods. Feature-specific repositories (e.g. TransferRepository, SearchRepository) call through DatabaseManager.
Schema migrations:
| Version | Tables added |
|---|---|
| v1 | transfers, search_queries, search_results, user_shares, shared_files, settings, transfer_history |
| v2 | buddies, my_interests, my_profile |
| v3 | blocked_users |
| v4 | private_messages |
| v5 | wishlists |
| v6 | sampleRate, bitDepth columns on search_results; localPath on transfer_history |
~/Library/Application Support/SeeleSeek/seeleseek.sqlite.
Feature Pattern
Each feature module follows a consistent structure:*State.swift holds all mutable state for the feature and exposes methods that are called from both the UI (button taps) and NetworkClient callbacks (incoming network events). Views read state via the environment and call methods on the state object.
Navigation
Navigation/ defines the sidebar item enum (.search, .transfers, .browse, etc.) and MainView, which switches the content area based on appState.sidebarSelection. The app uses a hidden title bar (windowStyle(.hiddenTitleBar)) with a default window size of 1200×800.
Design System
DesignSystem/ provides shared SwiftUI components and SeeleColors (including the accent color applied app-wide in seeleseekApp.swift).