Authentication
The Subsonic API supports two authentication modes: legacy password (p=) and token + salt (t= + s=). SwiftSonic uses the token mode by default — it never sends the user’s password as a query parameter.
Default: token authentication
Section titled “Default: token authentication”When you initialize a ServerConfiguration with a username and password, SwiftSonic generates a fresh token and salt for every request:
let config = ServerConfiguration( host: "music.example.com", username: "user", password: "pass")The password is hashed locally with the per-request salt; only t= and s= are sent on the wire.
Forcing password authentication
Section titled “Forcing password authentication”Some older servers do not support token auth.
TODO: document the exact way to opt into legacy password auth — confirm whether it is a
ServerConfigurationflag, an alternate initializer, or a property on a transport. Verify inSources/SwiftSonic/ServerConfiguration.swift.
Custom HTTP headers (Cloudflare Access, reverse proxies)
Section titled “Custom HTTP headers (Cloudflare Access, reverse proxies)”If your server sits behind Cloudflare Access, an OAuth proxy, or a reverse proxy that requires custom headers (CF-Access-Client-Id, CF-Access-Client-Secret, etc.), inject them via the custom transport:
TODO: write a worked example using
CustomHeadersTransport(or the equivalent type in 0.6.x). Confirm the type name and configuration shape fromSources/SwiftSonic/Transport/.
// TODO: replace with the actual API once verifiedlet transport = CustomHeadersTransport(headers: [ "CF-Access-Client-Id": "...", "CF-Access-Client-Secret": "..."])See Custom HTTP transport for the deep dive.
Failure modes
Section titled “Failure modes”When credentials are wrong, SwiftSonic surfaces a structured error you can branch on:
do { let albums = try await client.getAlbumList2(type: .recent)} catch let error as SwiftSonicError where error.isAuthenticationFailure { // prompt for credentials} catch { // bubble up}See Error handling for the full taxonomy.