This is a proof of concept of implementing a cache in WidgetKit. See https://codakuma.com/widgetkit-improvements for more.
Last active
August 13, 2024 19:23
-
-
Save shaundon/b4b823fbcac863d24c1ebe751cc97cfc to your computer and use it in GitHub Desktop.
Proof of concept of using caches in WidgetKit.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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 { | |
completion(nil) | |
return | |
} | |
completion([cachedEntry]) | |
return | |
} | |
// 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) | |
completion([entry]) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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