Imported from sebdanielsson/tagradar (
AGENTS.md). Install upstream withnpx skills add sebdanielsson/tagradar. Copyright stays with the author.
Tågradar — repo notes for AI assistants
- Native SwiftUI app, iOS 26.5+ built with the iOS 27 SDK (Xcode 27), Swift 6 strict concurrency. No third-party packages. Only Trafikverket's open data as data sources: the live Open API, plus NJDB track geometry bundled offline as
Tagradar/Resources/RailNetwork.json(seedocs/rail-network.md). - The Xcode project is generated: edit
project.yml, then runxcodegen(orScripts/bootstrap.sh). Never commitTagradar.xcodeproj. - API key:
.env.local→Scripts/bootstrap.sh→Config/Secrets.xcconfig→Info.plistkeyTRVAPIKey. Users can override in Settings (Keychain). Never commit keys. Packages/TrafikverketKitis platform-agnostic and testable withswift test. App-level logic tests live inTagradarTests.TagradarWidgetsis the WidgetKit extension (widgets + Live Activity UI). It compiles its own copy of the shared files listed inproject.yml(Tagradar/Models,TrainService,Formatters,SharedStorage, …); keep those free of app-only dependencies. App and extension share data through the App Groupgroup.se.tagradar.app(SwiftData store, station cache, alert state).- Notifications are local only (no push server):
TrainMonitorrefreshes saved/followed trains every 30 s in the foreground and viaBGAppRefreshTaskin the background, then feedsTrainAlerts(rules inTrainAlertEngine),LiveActivityControllerandWidgetCenter. A saved train's optionalTripSegment(boarding/alighting) is applied inTrainSnapshot, so all consumers see segment-relative delays.ActivityBackgroundRefresherkeeps Live Activities fresh in the background by chaining backgroundURLSessionuploads withearliestBeginDate(60 s en route); each completion wakes the app viaAppDelegate.application(_:handleEventsForBackgroundURLSession:). - User-facing strings are English source keys in
Tagradar/Resources/Localizable.xcstringswith Swedish translations. Code, comments and commits are in English. - Build:
xcodebuild -project Tagradar.xcodeproj -scheme Tagradar -destination 'platform=iOS Simulator,name=iPhone 17 Pro' build. - App icon:
Tagradar/AppIcon.icon(Icon Composer package, layers rendered byScripts/make-app-icon.swift). Never use SF Symbols in the icon (licence). Preview appearances with theictoolinside Icon Composer.app (seedocs/app-store.md). - Commits and PR titles follow Conventional Commits (
feat:,fix:,docs:,chore:,ci:…); release-please turns them into versions andCHANGELOG.md.version.txtandMARKETING_VERSIONinproject.ymlare bumped by the release PR only. CI/CD lives in one workflow (.github/workflows/ci.yml): verify → TestFlight onmain, release PR, App Store submission on release (seedocs/release.md). Code scanning is CodeQL advanced setup in.github/workflows/codeql.yml— Swift needs a realxcodebuildrun, so default setup's autobuild cannot analyse this repo (the Xcode project is generated). - Bundle identifier:
se.tagradar.appfor CI and releases (Jesper's team). Sebastian's personal team cannot register it, so.env.localsetsAPP_BUNDLE_ID=se.sebastiandanielsson.tagradar;project.ymlderives every identifier from$(APP_BUNDLE_ID:default=se.tagradar.app)and the code reads the App Group, Keychain group and background task ID from Info.plist. Never hard-code identifiers in Swift.