2026-11-04 15:01:22 +00:00
2026-11-04 15:01:22 +00:00
2026-11-04 14:59:42 +00:00
2026-11-04 14:59:42 +00:00
2026-11-04 14:59:42 +00:00
2026-11-04 14:59:42 +00:00
2026-11-04 15:01:22 +00:00
2026-11-04 14:59:42 +00:00

Tarnax

A native SwiftUI iPhone and iPad remote for qBittorrent. Downloads and files stay on your server. The default connection address is https://torrent.absdev.net. No credentials are included.

Build and run

  1. Unzip this folder and open Tarnax.xcodeproj in Xcode. Select the shared Tarnax scheme.
  2. Requires iOS/iPadOS 17 or later and an Xcode version with the iOS 17+ SDK. The delivered source was compiled using Xcode 27.2 and its iOS device SDK.
  3. Under target Signing & Capabilities, select your Apple development team and change the bundle identifier if necessary. The default is net.absdev.Tarnax.
  4. Select an iPhone/iPad simulator or your connected device and Run. A development-signed device build requires an Apple signing identity. The ZIP is source, not an installable IPA.
  5. Enter your qBittorrent Web UI username and password in the app. If your HTTPS proxy also uses HTTP Basic authentication, enter its separate credentials in the optional proxy fields.

No third-party packages, API keys, generated dependencies or backend service are required. Face ID requires a physical compatible device; device passcode authentication is also supported.

Command-line unsigned device build:

xcodebuild -project Tarnax.xcodeproj -scheme Tarnax \
  -configuration Debug -sdk iphoneos -destination 'generic/platform=iOS' \
  -derivedDataPath /tmp/TarnaxBuild CODE_SIGNING_ALLOWED=NO build

For a simulator, use -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' with an installed simulator runtime.

Connection and reverse proxy setup

Enable qBittorrent's Web UI and configure its username/password. Target qBittorrent 4.3+ or 5.x Web API v2. The app detects the application and API versions and uses stop/start on 5.x and pause/resume on 4.x. Individual APIs and preferences remain subject to your installed version and build configuration.

Use a valid HTTPS certificate trusted by iOS. Certificate verification and App Transport Security are enabled; the app does not accept arbitrary self-signed certificates. For a private CA, install and trust the CA using your organization's normal device configuration process.

Route /api/v2/ to the qBittorrent Web UI. A proxy subpath is supported: for https://example.net/qbit, the app requests /qbit/api/v2/.... Configure your proxy to strip that prefix if the upstream expects /api/v2/.... Avoid redirects on API routes. Login must return qBittorrent's Ok. response and an SID cookie rather than an HTML sign-in page.

The app supplies Origin and Referer for the public URL. Keep qBittorrent CSRF and host validation protections enabled. Configure the public hostname in qBittorrent's allowed domains and preserve the original host/protocol in the reverse proxy as required by your deployment. Pass Set-Cookie and Cookie headers through unchanged, with an externally usable cookie path/domain and Secure cookies for HTTPS. Forward Host, X-Forwarded-Host and X-Forwarded-Proto: https as appropriate for your proxy setup.

  • 401: Check the separate proxy Basic credentials. Interactive SSO, Cloudflare Access sign-in flows and client certificate authentication are not implemented.
  • 403: A session may have expired, host/CSRF checks may reject the request, or qBittorrent may have banned the IP after failed logins. Use Settings → Disconnect / change server to reconnect; check the server before repeatedly retrying passwords.
  • 404: Check the reverse proxy prefix and API route. An individual operation may be unavailable in that qBittorrent version.
  • TLS errors: Correct the certificate chain, hostname, or device trust configuration. The app deliberately has no insecure certificate override.

Features

  • Home: Only downloading, forcedDL, metaDL and forcedMetaDL. Seeding, completed, paused/stopped, stalled, queued, checking and error states stay in Library. Live progress, speeds, ETA, transferred size, totals and free disk space.
  • Library: Full list, name/category/tag search, status filtering and name/progress/speed/size/ETA sorting. Pull to refresh and context-menu pause/resume.
  • Add: Magnet links or a Files picker for .torrent files (up to 25 MB), save path, category, tags and paused state. Files are uploaded as multipart data, not interpreted locally.
  • Manage: Start/stop, force start/normal queue, recheck, reannounce, queue order, rename, move storage, category/tags, per-torrent speed limits, automatic management, add peers, sequential mode, first/last-piece priority and file rename. Delete confirmation offers remove-only or permanent server-file deletion.
  • Details: Live overview, every returned generic property, files with skip/normal/high/maximum priorities, peers with their returned information, and tracker status/add/edit/remove.
  • Server: qBittorrent/API versions, build information, global speeds/totals/limits, connection state, statistics and alternative speed mode.
  • Settings: Every preference returned by /app/preferences, grouped and searchable. Boolean switches, typed numeric validation, secure input for secret keys, text values and structured JSON editing for complex values. Writes send only the edited key to /app/setPreferences; confirmation precedes each change and a read-back checks the result. Network/Web UI/path changes can disconnect the app or move data. Settings use qBittorrent API units; consult the reference before changing unfamiliar advanced keys.
  • Security: Keychain credentials, HTTPS, private ephemeral SID cookie session, optional Face ID/device authentication when returning from background, light/dark appearance and adaptive iPad sidebar navigation.

RSS-related preferences returned by qBittorrent are editable. Dedicated RSS feed/rule management and server-side search plugin management are not included. Search refers to searching your torrent library. qBittorrent does not expose a separate historical download database; completion timestamps and other available history fields appear in torrent properties. The client is a remote control and does not download torrent contents to the iPhone/iPad.

Refresh, errors and privacy

The library and server summary refresh every 3 seconds while the app is active and unlocked; detail panels refresh every 5 seconds. iOS background execution is not requested, so live updates pause in the background. Long network operations have a 25-second timeout. Errors are visible; manual pull-to-refresh retries reads. Mutations are never automatically retried, avoiding duplicated uploads or destructive operations. Expired sessions require reconnecting.

Credentials are stored in a device-only Keychain item accessible while unlocked. SID cookies live only in the private session and are discarded on disconnect. Secrets are not placed in UserDefaults or logs. Only the app-lock preference is in UserDefaults. The app rejects HTTP and URLs containing userinfo/query credentials, and rejects redirects to another origin or to HTTP. All server settings, peers and torrent names come from your server; there is no analytics service.

Use Settings → Forget saved credentials to remove the Keychain item and disconnect. iOS can retain Keychain items across app reinstalls; remove credentials explicitly when retiring a device. App authentication uses Face ID/Touch ID when available and allows the device passcode fallback. It protects the interface, while Keychain data uses the device's existing unlock protection.

Project layout

  • Tarnax/App.swift: app lifecycle, connection, navigation, library and add form.
  • Tarnax/Core.swift: models, transport, private session, Keychain and app state.
  • Tarnax/Details.swift: torrent details and management.
  • Tarnax/Settings.swift: server statistics and schema-driven preference editing.
  • Tarnax/Info.plist, Assets.xcassets: iPhone/iPad configuration, Face ID purpose and app icon.
  • Tests/ContractTests.swift, Tests/run.sh: executable macOS contract checks using a mocked URL loading protocol; no server or real credentials required.

Run contract checks on a Mac with Xcode selected:

./Tests/run.sh

The harness tests unsafe URL rejection, proxy subpaths, form encoding (including Unicode and punctuation), CSRF headers, optional Basic auth, GET queries, empty file decoding, login failure, safe HTTP errors, multipart uploads and the exact Home state policy. It compiles the actual transport/model source, not a duplicate implementation.

See VALIDATION.md for results and manual acceptance checks. No live account login or device UI test was performed during packaging.

API reference: https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-5.0)

Tarnax startup and branding

Tarnax automatically signs in once per launch when a saved server and username are available in Keychain. App protection must be unlocked first. Failed sign-in returns to the connection form; explicit disconnect prevents automatic sign-in again during the same launch.

The native launch storyboard and connecting view share the Tarnax orbital mark. AppIcon uses an opaque 1024×1024 universal iOS icon; Xcode generates the required device sizes.

Build, test and direct-install IPA

Use scripts/test.sh, scripts/build.sh --release and scripts/release.sh. See scripts/README.md for signing requirements, export methods, provisioning controls and output locations. Direct-install IPAs are limited to provisioned devices.

S
Description
qTorrent IOS Client
Readme
20 MiB
Languages
PHP 34.2%
Swift 30.8%
Blade 23.6%
Python 6.8%
Shell 3.6%
Other 0.9%