import ActivityKit import BackgroundTasks import SwiftUI @main struct FuelBoardApp: App { init() { WatchSyncManager.shared.activate() SmartDataRefreshScheduler.register() #if DEBUG // QA hook (Debug builds only): `-qaLiveActivity e10|e5|diesel` starts a // Live Activity with a long station name so the Lock Screen / island // layout can be rendered in the Simulator for visual QA. let args = ProcessInfo.processInfo.arguments if let idx = args.firstIndex(of: "-qaLiveActivity"), args.indices.contains(idx + 1), let fuel = FuelType(rawValue: args[idx + 1]) { startQALiveActivity(fuel: fuel) } #endif } var body: some Scene { WindowGroup { ContentView() .onOpenURL(perform: handleOpenURL) .onReceive(NotificationCenter.default.publisher(for: .fuelBoardWatchRefreshRequested)) { _ in WatchSyncManager.shared.pushSnapshot() } } .backgroundTask(.appRefresh(SmartDataRefreshScheduler.taskIdentifier)) { await SmartDataRefreshCoordinator.runBackgroundProbe() } } #if DEBUG private func startQALiveActivity(fuel: FuelType) { let state = FuelBoardLiveActivityAttributes.ContentState( fuel: fuel, stationID: "qa-phoenix", stationName: "Phoenix Filling Stations", brand: "Phoenix", pricePence: 1499, priceDisplayStyle: FuelStore.loadPriceDisplayStyle(), distanceKM: 8.0, lat: 51.5, lng: -0.12, updatedAt: Date() ) let attrs = FuelBoardLiveActivityAttributes() do { let activity = try Activity.request( attributes: attrs, content: .init(state: state, staleDate: nil), pushType: nil ) print("QA-LIVE-ACTIVITY STARTED id=\(activity.id)") } catch { print("QA-LIVE-ACTIVITY FAILED: \(error)") } } #endif /// Handles deep links that end up in the app. Widget taps arrive here in /// two cases: /// - legacy/cached widget timelines using the `fuelboard://` relay, or /// - the Home Screen delivering a `maps://` URL to the containing app /// instead of opening Maps directly (the system's choice on iOS). /// Either way we forward to the native Apple Maps directions URL. The /// `http://maps.apple.com` form is also handled, from very old timelines. /// In CarPlay the widget uses the same `maps://` URL, which routes to /// Apple Maps without ever launching this app. private func handleOpenURL(_ url: URL) { guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let items = components.queryItems else { return } // Preferred: maps://?daddr=lat,lng&t=d (also covers http://maps.apple.com). if let daddr = items.first(where: { $0.name == "daddr" })?.value { openMaps(daddr: daddr) return } // Legacy relay: fuelboard://directions?lat=..&lng=.. if let lat = items.first(where: { $0.name == "lat" })?.value.flatMap(Double.init), let lng = items.first(where: { $0.name == "lng" })?.value.flatMap(Double.init) { openMaps(daddr: "\(lat),\(lng)") } } private func openMaps(daddr: String) { guard let mapsURL = URL(string: "maps://?daddr=\(daddr)&t=d") else { return } UIApplication.shared.open(mapsURL) } }