How to "force" WidgetKit TimelineProvider to render placeholders?

I have a special use case for the widgets where the user must give permission for the main app to share data with the widget. As such, the widget/app share a common database, and if permissions are given, the app writes relevant data to the DB. If permissions are NOT given, then the app will delete the DB "entry", and calls reloadAllTimelines() to refresh.

In my getTimeline function, I use an asynchronous function to return an optional struct conforming to TimelineEntry. So if there is data in the DB (given permission) said function returns a valid struct, and if there is no data (not given permission) the function returns nil.

The problem is, the getTimeline function has a non-optional callback parameter of type TimelineEntry. So when I call the data class to return my Entry object, and it returns with a valid object, I simply call callback(entry). I am confused as to what I need to do when I am returned a nil entry object. Simply returning from the function without calling callback would make sense, as I assume not calling the callback would make the OS decide to show placeholder, but my assumption seems to be wrong.

So, how would I achieve the effect of "invalidating" the data from the widget, and "forcing" it to re-fetch the data, and show placeholder as it does on first load when it has no data?

Additionally, I have breakpoints set in the getTimeline function of the widget, and I am currently debugging the widget target. What I notice is when I go to the main application from a fresh run, and enable the widget "permission", within 30 or so seconds, the widget will update with the data the main app just put in. This is confirmed by the breakpoints triggering, and inspecting the info coming back from CoreData. Upon disabling the permission in the main app, calling WidgetCenter.shared.reloadAllTimelines() triggers the widget target's breakpoints again, and I can also confirm that the data is, in fact, gone from the DB, as no info is returned from CoreData. As such, the getTimeline function gets a nil entry, and returns without calling the completion handler. Upon inspection of the Widget, the previous state of the widget persists indefinitely.

This doesn't seem to even fix itself after the 20 minute refresh date I have set. If I wipe the info from the shared DB, even after my widget's supposed refresh date given to the timeline, the previous state still persists.

Any help is greatly appreciated!
Though I am not certain, I speculate maybe the widgets are not meant to go back to the placeholder state after they've transitioned out of it. I can not seem to find any documentation related to this topic, however so that is only speculation at the moment.
Accepted Answer
I'm not sure if this would work for your case but you could just add a field like "applyRedaction" to your entry object, set that to true in the case where your widget doesn't have permission, fill in the rest of the field with static data like you do in getSnapshot() and return the entry from getTimeline using the completion method as in the success case.

Then in your widget main entry struct where the view is returned you can just manually apply the redaction based on the value of the applyRedaction value e.g.

Code Block swift
if entry.applyRedaction {
return AnyView(Text("Hello").redacted(reason: .placeholder))
} else {
return AnyView(Text("Hello"))
}


I use this pattern in my widget to just show a redacted view of my widget in the case that there are any transient network errors.
How to "force" WidgetKit TimelineProvider to render placeholders?
 
 
Q