Files
fuelboard/Shared/FuelBoardLiveActivity.swift
T
FuelBoard Contributor 04b233bf9a Live Activity: cheapest-in-radius Lock Screen/Dynamic Island pill
- Shared FuelBoardLiveActivityAttributes/ContentState (app + widget targets)
- FuelBoardLiveActivity Widget: ActivityConfiguration rendered by the widget
  extension - Lock Screen banner + Dynamic Island (leading/trailing/bottom,
  compact, minimal), tap anywhere -> maps:// directions to the best station
- LiveActivityManager (app side): request/update/end; mirrors the app list's
  TOP badge (selected fuel + chosen distance radius, price-then-distance
  ties); local start-date tracking for the 8h cap (this SDK's Activity has no
  startDate) - auto-restarts at 7h59m; silent no-op when disabled/denied
- Wiring: 250m/60s location hook (incl. background significant-change
  wake-ups), refresh completion, fuel/radius/unit changes, toggle flip
- Settings toggle + FuelStore persistence (keychain-backed, app-group)
- App-Info.plist: NSSupportsLiveActivities
2026-08-12 20:11:42 +01:00

33 lines
1.3 KiB
Swift

// FuelBoardLiveActivity.swift — Live Activity shared model.
//
// Compiled into BOTH the app target (to start/update/end the activity) and
// the widget extension (to render it). ActivityKit is iOS-only, so this file
// is deliberately NOT symlinked into FuelBoardTests/Sources — the SPM test
// target runs on macOS where ActivityKit does not exist.
//
// The activity mirrors the app's TOP badge: the cheapest station selling the
// app's selected fuel within the app's chosen distance radius. Tapping the
// activity opens Apple Maps driving directions to that station (maps://).
import ActivityKit
import Foundation
/// Attributes are fixed at request time. Here they pin the FUEL being
/// tracked; everything that can change while driving (station, price,
/// distance) lives in ContentState so updates don't need a new activity.
struct FuelBoardLiveActivityAttributes: ActivityAttributes {
var fuel: FuelType
public struct ContentState: Codable, Hashable {
var stationID: String
var stationName: String
var brand: String
/// Price in pence per litre (same unit as `FuelStation.prices`).
var pricePence: Double
var distanceKM: Double
var lat: Double
var lng: Double
var updatedAt: Date
}
}