Skip to content

Instantly share code, notes, and snippets.

Last active February 26, 2023 02:53
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save shaundon/b4b823fbcac863d24c1ebe751cc97cfc to your computer and use it in GitHub Desktop.
Proof of concept of using caches in WidgetKit.
Most of this file has been omitted to only focus on the caching aspect, but in reality
it would be a standard widget template.
struct MyWidgetProvider: IntentTimelineProvider {
// Initialise the cache.
private let cache = MyWidgetCache()
func getEntries(for configuration: ConfigurationIntent, in context: Context, completion: @escaping ([MyWidgetEntry]?) -> ()) {
getWorkouts { error, workouts in
// If something goes wrong, try to use a cached entry.
if let error = error {
guard let cachedEntry = cache.newEntryFromPrevious(withDate: Date(), forConfiguration: configuration) else {
// If no errors, make an entry, cache it, and return it.
let entry = MyWidgetEntry(date: Date(), configuration: configuration, workoutsCount: workouts.count)
cache.storePreviousEntry(entry, withConfiguration: configuration)
class MyWidgetCache: WidgetCache {
typealias TimelineEntryType = MyWidgetEntry
typealias ConfigurationIntentType = MyWidgetConfigurationIntent
var previousEntries = [MyWidgetConfigurationIntent: MyWidgetEntry]()
func newEntryFromPrevious(withDate date: Date, forConfiguration configuration: MyWidgetConfigurationIntent) -> MyWidgetEntry? {
if previousEntries.isEmpty { return nil }
guard let indexOfPreviousEntry = previousEntries.index(forKey: configuration) else { return nil }
let previousEntry = previousEntries[indexOfPreviousEntry].value
return MyWidgetEntry(
date: date,
configuration: previousEntry.configuration,
workoutsCount: previousEntry.workoutsCount
func storeNewEntry(_ entry: MyWidgetEntry, withConfiguration configuration: MyWidgetConfigurationIntent) {
previousEntries[configuration] = entry
protocol WidgetCache {
associatedtype TimelineEntryType: TimelineEntry
associatedtype ConfigurationIntentType: INIntent
var previousEntries: [ConfigurationIntentType: TimelineEntryType] { get set }
func newEntryFromPrevious(withDate date: Date, forConfiguration configuration: ConfigurationIntentType) -> TimelineEntryType?
func storeNewEntry(_ entry: TimelineEntryType, withConfiguration configuration: ConfigurationIntentType) -> Void
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment