Contents

serotonincrash/folibusapi

A native Swift package for accessing the Föli (Turku Region Public Transport) real-time public transport API. It's quick, utilising modern Swift Concurrency and a modern `await`able API, and a built in caching layer.

Disclaimer

This API is an experimental project for me to try out Xcode's new agentic programming systems. Whilst I will personally do my best to maintain and review the code generated by AI models, I cannot personally guarantee that the wrapper will continue working. The Föli data API updates frequently. Use at your own risk.

Docs are a work in progress and generated by AI models.

Overview

FoliBusAPI provides async Swift interfaces for:

  • SIRI stop monitoring and real-time arrivals
  • GTFS routes, stops, trips, stop times, and calendar dates
  • Optional on-disk caching for GTFS-backed resources
  • SwiftUI-friendly access through FoliService and client providers
  • Transport injection for tests and advanced networking setups

The package is built around FoliClient, an actor that owns request execution, response decoding, in-flight deduplication, and cache coordination.

Requirements

  • iOS 15.0+
  • macOS 12.0+
  • watchOS 8.0+
  • tvOS 15.0+
  • Swift 6.2 toolchain

Installation

Swift Package Manager

Add the package to your Package.swift dependencies:

.package(url: "https://github.com/serotonincrash/FoliBusAPI.git", branch: "main")

Then add the product to your target:

.target(
    name: "MyApp",
    dependencies: [
        .product(name: "FoliBusAPI", package: "FoliBusAPI")
    ]
)

Common usage patterns

Direct client usage

import FoliBusAPI

let client = FoliClient(
    cacheBehavior: .forceRefresh,
    cacheTimeout: .default
)

let routes = try await client.fetchRoutes()
let stopMonitoring = try await client.fetchStopMonitoring(for: "1000")
let arrivals = try await client.fetchArrivals(for: "1000")

Shared convenience facade

import FoliBusAPI

let routes = try await FoliBusAPI.fetchRoutes()
let arrivals = try await FoliBusAPI.fetchArrivals(for: "1000")

SwiftUI integration

import SwiftUI
import FoliBusAPI

@main
struct DemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(
                    \.foliClientProvider,
                    DefaultFoliClientProvider(
                        configuration: FoliClientConfiguration(
                            cacheBehavior: .staleWhileRevalidate,
                            cacheTimeout: .default
                        )
                    )
                )
        }
    }
}

struct ContentView: View {
    @FoliService var foliService
    var stopId: String
    @State var arrivals: [Foli.Arrival] = []
    var body: some View {
        List(arrivals, id: \.id) { arrival in
            Text(arrival.lineRef)
        }
        .task {
            do {
                arrivals = try await foliService.fetchArrivals(for: stopId)
            } catch {
                print("Failed to fetch arrivals: \(error.localizedDescription)")
            }
        }
    }
}

Inject a custom transport

import Foundation
import FoliBusAPI

let client = FoliClient(
    transport: URLSessionTransport(session: .shared),
    cacheBehavior: .cachedOrFetch
)

Caching

GTFS-backed resources support the following cache strategies:

  • cachedOrFetch
  • staleWhileRevalidate
  • forceRefresh
  • cachedOnly
  • noCache

Use staleWhileRevalidate when you want fast UI reads backed by a best-effort background refresh. If metadata revalidation fails transiently, the existing cached value remains usable until a later refresh succeeds.

Use forceRefresh when you need the freshest known data.

Documentation

The package includes a .docc catalog under Sources/FoliBusAPI/FoliBusAPI.docc.

If your local toolchain supports DocC generation, you can build docs with Xcode:

xcodebuild docbuild \
  -scheme FoliBusAPI \
  -destination 'platform=macOS,arch=arm64,name=My Mac' \
  -derivedDataPath .build/DerivedData \
  -resultBundlePath .build/FoliBusAPI-docbuild.xcresult

Development

Run the test suite with:

swift test

Package Metadata

Repository: serotonincrash/folibusapi

Default branch: main

README: README.md