The no-network last resort (bundled real dump) now shows a tappable banner above the tabs — 'Offline data from 15 Aug / Pull to refresh to update prices' — so stale snapshot data is never presented as live. Banner date comes from the dump's own data_updated stamp (FuelStore.offlineDataLabel, ISO 8601 with/without fractional seconds). Cleared on any successful fetch. - BundledDumpProvider.dataUpdatedStamp (JSONSerialization, app target) - ContentView: offlineDataDate state, offlineBanner view (tip-card styling, orange wifi.slash + arrow.clockwise, tap = force refresh), refresh() clears/sets it, -forceOfflineDump QA launch hook (serves the dump and skips auto-refresh so the banner stays up for captures) - Localizable.strings: 3 keys (banner title/subtitle/a11y) - +3 tests: OfflineDataLabelTests (101 total)
29 lines
1.3 KiB
Swift
29 lines
1.3 KiB
Swift
// BundledDumpProvider.swift — no-network last resort (P0 live chain).
|
|
//
|
|
// A REAL snapshot of the mirror dump is bundled into the app (FuelBoardDump
|
|
// dataset, refreshed before builds by scripts/refresh_bundled_dump.sh) so the
|
|
// app never demos empty and App Review always sees real data even fully
|
|
// offline. Same relay envelope, so the shared decode applies unchanged.
|
|
|
|
import UIKit
|
|
|
|
enum BundledDumpProvider {
|
|
/// The bundled real snapshot, decoded with the shared relay decode —
|
|
/// nil only if the asset is missing or corrupt (callers then fall back
|
|
/// to the England-wide sample set).
|
|
static var stations: [FuelStation]? {
|
|
guard let asset = NSDataAsset(name: "FuelBoardDump") else { return nil }
|
|
return try? FuelPriceProvider.decodeStations(from: asset.data)
|
|
}
|
|
|
|
/// The GOV.UK `data_updated` stamp from the bundled envelope (ISO 8601).
|
|
/// Labels the offline-data banner honestly ("Offline data from 15 Aug")
|
|
/// instead of presenting the build's snapshot as live.
|
|
static var dataUpdatedStamp: String? {
|
|
guard let asset = NSDataAsset(name: "FuelBoardDump"),
|
|
let obj = try? JSONSerialization.jsonObject(with: asset.data)
|
|
as? [String: Any] else { return nil }
|
|
return obj["data_updated"] as? String
|
|
}
|
|
}
|