A type that advises WidgetKit when to update a widget's display.
At various times, WidgetKit requests a _timeline_ from the provider. A
timeline is an array of objects conforming to <doc:TimelineEntry>. Each
timeline entry has a date, and you can specify additional properties
for displaying the widget.
For example, consider a widget that displays the health level of a game
character. In the game, when the character's health level is below 100
percent, it recovers at a rate of 25 percent per hour. If the character's
health level is 25 percent, the provider creates a timeline consisting of
the following entries:

The following code shows the structure encapsulating this information.
struct CharacterDetailEntry: TimelineEntry {
var date: Date
var healthLevel: Double
}
WidgetKit asks for timeline entries in one of two ways:
* A single immediate snapshot, representing the widget’s current state.
* An array of entries, including the current moment and, if known, any
future dates when the widget’s state will change.
WidgetKit makes the snapshot request when displaying the widget in
transient situations, such as when the user is adding a widget. WidgetKit
provides a `context` parameter that includes details about how to use the
entry, including whether it’s a preview for the widget gallery, and the
family, or size, of the widget to display. If `context.isPreview` is
`true`, the widget appears in the widget gallery and requires a quick
response from your provider. If the information you need to generate the
snapshot is not readily available, or requires additional time to load, use
sample data instead. For example, if determining the character's health
level requires fetching data from a server, the widget could show the
health level at 75 percent. The following code shows how the game widget
might implement its snapshot method.
struct CharacterDetailProvider: TimelineProvider {
func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
let date = Date()
let entry: CharacterDetailEntry
if context.isPreview && !hasHealthLevel {
entry = CharacterDetailEntry(date: date, healthLevel: 0.75)
} else {
entry = CharacterDetailEntry(date: date, healthLevel: currentHealthLevel)
}
completion(entry)
}
}
WidgetKit makes the timeline request after the user adds your widget from
the widget gallery. Because your widget extension is not always running,
WidgetKit needs to know when to activate it to update the
widget. The timeline your provider generates informs WidgetKit when you
would like to update the widget. The following example shows how the
<doc://com.apple.documentation/documentation/widgetkit/emoji-rangers-supporting-live-activities-interactivity-and-animations>
sample code project creates a timeline for its leaderboard widget.
func getTimeline(in context: Context, completion: @escaping (Timeline<LeaderboardEntry>) -> Void) {
EmojiRanger.loadLeaderboardData { (heros, error) in
guard let heros else {
let timeline = Timeline(entries: [LeaderboardEntry(date: Date(), heros: EmojiRanger.availableHeros)], policy: .atEnd)
completion(timeline)
return
}
let timeline = Timeline(entries: [LeaderboardEntry(date: Date(), heros: heros)], policy: .atEnd)
completion(timeline)
}
}
If your provider needs to do asynchronous work to generate the timeline,
such as fetching data from a server, store a reference to the
`completion` handler and call it when you are done with your asynchronous
work.
### Determine a refresh policy
When creating the timeline, the provider specifies a refresh policy that
controls when WidgetKit requests a new timeline. The default
behavior is to use ``WidgetKit/TimelineReloadPolicy/atEnd`` to request a new timeline after the last date
specified by the entries in a timeline. However, if there is a different
date when WidgetKit should request a new timeline, you can specify a
refresh policy of ``WidgetKit/TimelineReloadPolicy/after(_:)``. For example, a dragon will appear in
2.5 hours and might engage in battle with the game character. Because the
outcome of this battle may change the character's health level, the
provider can tell WidgetKit to request a new timeline after the battle.
// Request a timeline refresh after 2.5 hours.
let date = Calendar.current.date(byAdding: .minute, value: 150, to: Date())!
let timeline = Timeline(entries: entries, policy: .after(date))
completion(timeline)
Other examples of when it makes sense to use a different date include:
* In a widget displaying stock market details, you might specify the next
market opening or closing date because information typically doesn't
change overnight or during weekends.
* A flight tracking widget might continue showing a “flight
landed” indication after the flight lands. In this case, you could
specify a date later than when the flight lands so that its status
remains visible for a while before being cleared.
Alternatively, if future events are unpredictable, you can tell WidgetKit
to not request a new timeline at all by specifying ``WidgetKit/TimelineReloadPolicy/never`` for the
policy. In that case, your app calls the <doc:WidgetCenter> function
<doc:WidgetCenter/reloadTimelines(ofKind:)> when a new timeline is
available. Some examples of when using ``WidgetKit/TimelineReloadPolicy/never`` makes sense include:
* When the user has a widget configured to display the health of a
character, but that character is no longer actively engaging in battle
and its health level won't change.
* When a widget’s content is dependent on the user being logged into an
account and they aren’t currently logged in.
In both examples, when your app determines that the status has changed, it
calls the <doc:WidgetCenter> function
<doc:WidgetKit/WidgetCenter/reloadTimelines(ofKind:)> and WidgetKit
requests a new timeline.
### Refresh widgets efficiently
Each configured widget receives a limited number of refreshes every day. Several
factors affect how many refreshes a widget receives, such as
whether the containing app is running in the foreground or background, how
frequently the widget is shown onscreen, and what types of activities the
containing app engages in.
- Note: WidgetKit does not impose this limit when debugging your widget in
Xcode. To verify that your widget behaves correctly, test your app and
widget's behavior outside of Xcode's debugger.
Use the following approaches to optimize your widget refreshes:
* Have the containing app prepare data for the widget in advance of when the
widget needs it. Use a shared group container to store the data.
* Use background processing time in your app to keep shared data up to date.
For more information, see
<doc://com.apple.documentation/documentation/uikit/using-background-tasks-to-update-your-app>.
* Choose the most appropriate refresh policy for the information being shown,
as described in the preceding section.
* Call <doc:WidgetCenter/reloadTimelines(ofKind:)> only when information
the widget is currently displaying changes.
When your app is in the foreground, has an active media session, or
is using the standard location service, refreshes don't count against the
widget's daily limit. For more information about media sessions and location
services, see
<doc://com.apple.documentation/documentation/avfaudio/avaudiosession>
and
<doc://com.apple.documentation/documentation/corelocation/configuring-your-app-to-use-location-services>.
Members (1)
method · iOS 18.0+
relevance
Swift declaration
func relevance() async -> WidgetRelevance<Void>
Provides an object containing attributes that describe when a specific
widget is relevant.
The system can use the relevance to show this widget in the Smart Stack
when the provided relevance matches a person's context. For example,
if you indicate relevance at a specific location, the system could
show the widget when a person is at or close to the location.
By default, this method returns no relevances. Implement this
requirement to tell the system that your widget is relevant.
> Note: Smart Stacks are available in iOS, iPadOS, and watchOS.
However, functionality provided by RelevanceKit API is only available
in watchOS. Calling its API on other platforms doesn't have any effect.
For more information, refer to <doc:Widget-Suggestions-In-Smart-Stacks>.
- Returns: The object that contains attributes that describe when a specific
widget is relevant.