Not understanding TimelineReloadPolicy in WidgetKit

Relevant docs: https://developer.apple.com/documentation/widgetkit/timelinereloadpolicy

I don't understand how .atEnd and .after works and how they differ.

So here's what I want: I want to display my widget then update it in 5 seconds. Now I know these examples show that I can use the .after policy like so:

 let timeline = Timeline(
            entries:[entry],
            policy: .after(nextUpdateDate) // 5 seconds after now
        )

But from reading the docs, .atEnd means: "A policy that specifies that WidgetKit requests a new timeline after the last date in a timeline passes."

So why can't we do:

let timeline = Timeline(
            entries:[entry1, entry2], // entry 2 has date 5 seconds after
            policy: .atEnd
        )

I tried this and it does not seem to work. When I say I tried, I just had an onAppear on my widget view to print out the entry dates, and the entry 5 seconds later never prints. So what does .atEnd actually do? What happens if we put .atEnd with 1 entry?

Answered by Engineer in 814249022

A quick synopsis:

You get 10MB of space per timeline. You get 72 refreshes per day and an unlimited amount of entries.

This means you can create a timeline of size 10MB and refresh every 20 minutes.

.atEnd tells your Widget process to request a new timeline after the last entry is called.

.after tells your Widget process to request a new timeline after the last entry is called and a certain amount of time has passed.

The system, or Springboard essentially, will reload if resources are available to do such. None of this is guaranteed. OnAppear isn't really valid for Widgets because they don't explicitly have a lifecycle and UI should be driven by your entry values, not runtime updates when the UI appears. The views themselves are archived and saved as a timeline so even in onAppear things aren't editable.

Lastly, if you think there is an issue with reloading, the best first course of action would be to use Console.app to monitor to the relevant processes related to your app and extensions.

A good way to start would be with filtering by the BundleID of the target and / or the target name itself (the process name).

To debug WidgetKit, LiveActivities, Dynamic Island you'll want to monitor springboardd, liveactivitiesd along with other relevant processes.

Rico


WWDR | DTS | Software Engineer

Accepted Answer

A quick synopsis:

You get 10MB of space per timeline. You get 72 refreshes per day and an unlimited amount of entries.

This means you can create a timeline of size 10MB and refresh every 20 minutes.

.atEnd tells your Widget process to request a new timeline after the last entry is called.

.after tells your Widget process to request a new timeline after the last entry is called and a certain amount of time has passed.

The system, or Springboard essentially, will reload if resources are available to do such. None of this is guaranteed. OnAppear isn't really valid for Widgets because they don't explicitly have a lifecycle and UI should be driven by your entry values, not runtime updates when the UI appears. The views themselves are archived and saved as a timeline so even in onAppear things aren't editable.

Lastly, if you think there is an issue with reloading, the best first course of action would be to use Console.app to monitor to the relevant processes related to your app and extensions.

A good way to start would be with filtering by the BundleID of the target and / or the target name itself (the process name).

To debug WidgetKit, LiveActivities, Dynamic Island you'll want to monitor springboardd, liveactivitiesd along with other relevant processes.

Rico


WWDR | DTS | Software Engineer

Not understanding TimelineReloadPolicy in WidgetKit
 
 
Q