SwiftF1Telemetry is a pure Swift package for loading, parsing, caching, and processing Formula 1 telemetry data directly on device.
The project is inspired by the behavior of FastF1, but it is not a pandas-style port. Instead, it provides a Swift-native API built around typed models, async/await, disk caching, telemetry processing, and chart-ready outputs.
Current documented release: 0.4.2
- The official package documentation lives in the repository
docs/folder and is intended to be the single source of truth for package usage and API guidance. - Start from docs/overview.md for the documentation hub.
- Swift Package Index is configured to link to that external documentation.
Repository guides:
SwiftF1Telemetry is currently in early development.
Implemented:
- Real session resolution from archive data
- Discovery APIs for available years, events, sessions, and drivers
- Enriched driver discovery (number, name, surname, abbreviation, team)
- Fastest-lap lookup and telemetry extraction (by driver number or name-based identifier)
- Two-lap / two-driver fastest-lap telemetry comparison
- Chart-ready telemetry and comparison series
- Disk caching with configurable storage profiles
- Public Codable models and CLI smoke usage (
f1-cli)
In progress:
- Additional FastF1 parity for edge-case lap reconstruction
- Broader cross-season and cross-session validation
- Linux CI/runtime hardening and Android bridge work
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/Al3x18/SwiftF1Telemetry.git", from: "0.4.1")
]Then add the product to your target:
dependencies: [
.product(name: "SwiftF1Telemetry", package: "SwiftF1Telemetry")
]import SwiftF1Telemetry
let client = F1Client()
let session = try await client.session(
year: 2024,
meeting: "Monza",
session: .qualifying
)
guard let lap = try await session.fastestLap(driver: "16") else {
return
}
let telemetry = try await session.telemetry(for: lap)
print("Lap:", lap.lapNumber)
print("Lap time:", lap.lapTime ?? 0)
print("Samples:", telemetry.samples.count)
print("Speed series points:", telemetry.speedSeriesByDistance().count)You can also customize cache behavior:
var configuration = F1Client.Configuration.default
configuration.cacheMode = .medium
let client = F1Client(configuration: configuration)You can also compare two drivers directly:
let comparison = try await session.compareFastestLaps(
referenceDriver: "16",
comparedDriver: "55"
)
print("Final delta:", comparison.finalDelta ?? 0)
print("Delta points:", comparison.deltaSeriesByDistance().count)
print("Reference speed points:", comparison.referenceSpeedSeriesByDistance().count)
print("Compared speed points:", comparison.comparedSpeedSeriesByDistance().count)Driver lookup supports number, surname, and abbreviation:
let byNumber = try await session.fastestLap(driver: "16")
let bySurname = try await session.fastestLap(driver: "Leclerc")
let byAbbreviation = try await session.fastestLap(driver: "LEC")And you can guide users through discovery instead of asking them to guess input values:
let years = try await client.availableYears()
let events = try await client.availableEvents(in: 2024)
let sessions = try await client.availableSessions(in: 2024, event: "Monza")
let drivers = try await client.availableDrivers(in: 2024, event: "Monza", session: .qualifying)Discovery APIs throw typed F1TelemetryError values when the requested year, event, session, or driver list is not available, so callers can guide users without falling back to generic network error handling.
Run the test suite with:
swift testRun the CLI smoke test with:
swift run f1-cli 2024 Monza Q 16Try the discovery flow with:
swift run f1-cli discover
swift run f1-cli discover 2024
swift run f1-cli discover 2024 Monza
swift run f1-cli discover 2024 Monza QTelemetry lookup also accepts names:
swift run f1-cli 2024 Monza Q 16
swift run f1-cli 2024 Monza Q Leclerc
swift run f1-cli 2024 Monza Q LEC
swift run f1-cli 2024 Monza Q Leclerc SainzThe discovery command uses the archive-backed years and sessions that are actually available to the library. If a year or session is not exposed by the official archive, the CLI now reports that clearly instead of surfacing a raw HTTP error.
This package follows the standard Swift Package Manager versioning model:
- use Semantic Versioning
- create Git tags such as
1.0.0,1.0.1 - publish GitHub Releases from those tags
- treat the Git tag as the authoritative package version
Example dependency declaration:
.package(url: "https://github.com/Al3x18/SwiftF1Telemetry.git", from: "0.4.1")Package.swift does not contain a version field, and that is correct for Swift packages.
The repository includes:
CHANGELOG.mdfor release notesCONTRIBUTING.mdfor contribution guidelinesLICENSEwith the MIT license textSwiftF1TelemetryVersion.currentas a convenience runtime string
Detailed package usage and API guidance live in docs/overview.md.