Stop Polling APIs in Widgets: Build a Snapshot Broker Instead
A widget should be a fast reader, not a network-heavy client. If every timeline request hits your API, refresh budgets disappear and stale UI follows. A snapshot broker pattern fixes this.
Step 1: centralize data fetch in the host app
struct WidgetSnapshot: Codable {
let generatedAt: Date
let headline: String
let progress: Double
}
Step 2: persist snapshots to shared app group storage
let url = FileManager.default
.containerURL(forSecurityApplicationGroupIdentifier: "group.learnitfree")!
.appendingPathComponent("widget-snapshot.json")
Step 3: let widget timeline read local snapshot first
let entry = try SnapshotStore.load() ?? .placeholder
return Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(1800)))
Pitfall
Making widget extension own API auth and retries. This creates fragile, battery-hungry behavior.
Verification
- Widget renders instantly from local snapshot.
- Host app refresh updates next widget timeline cycle.
- API outages do not blank out widget content.