My widgets appear with a Placeholder view in the Widget Gallery

I have multiple widgets in my application, and they all appear as the "placeholder" view.

In my snapshot code (shown below), the information is returned in less than a second. I even tried using sample data rather than retrieving the data from HealthKit (the commented out code).

In fact, you can briefly see the data show up in Widget Gallery in a video I took, before it switches to the placeholder view. (For some reason the forums aren't allowing me to link to the video)

Any idea what's going on?

Code Block swift
public func snapshot(for configuration: HealthStatTypeSelectionIntent, in context: Context, completion: @escaping (HealthEntry) -> ()) {
print("HealthWidget.snapshot ")
let entry = HealthEntry(date: Date(), stat: HealthStat(type: .steps) )
completion(entry)
// HealthKitHelper.shared.getStats(for: .steps) { stat in
// let entry = HealthEntry(date: Date(), stat: stat )
// completion(entry)
//
// }
}


Your widget process is crashing. Connect via Console and check the logs. Perhaps missing entitlements?
If you don't pass any timeline entries, then widget will be showing redacted view(placeholder view).

Snapshot method is solely for the purpose of explaining to user of how the widget will look like?

Timeline method is the actual method which will show content on these widgets. You need to pass multiple entries to the callback method, which in-turn renders your views according to the date entries that you have passed.

In your case, implement the timeline method and pass some entries, thereby you can see your widget views rendered.
When I actually add the widget to the homescreen, the widget displays properly.

From the documentation, snapshot appears to be what is used for the Widget Gallery view:


WidgetKit calls snapshot(for:with:completion:) when the widget appears in transient situations. If context.isPreview is true, the widget appears in the widget gallery.

Regardless, I am passing entries in the timeline - below is my code. I'm only providing one timeline entry since I want to refresh the data every 15 minute increments. (This is an agenda widget, so I want to load any new calendar events, etc). I set the entry date for the 15 minute mark so it refreshes roughly every 15 minutes.

I also tried passing two entries: one for Date(), and one with the Refresh date below, and I still see the same issue.

Code Block swift
var entries: [SimpleEntry] = []
let refreshDate = DateHelper.shared.nextWidgetRefreshDate(frequency: 15)
let agendaViewModel = AgendaViewModel()
agendaViewModel.getData(hidePastEvents: true) {
let agendaItemsByDate = Array(agendaViewModel.agendaItemsByDate.prefix(2))
let entry = SimpleEntry(date: refreshDate, agendaItemsByDate: agendaItemsByDate)
entries.append(entry)
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}


Ok, I figured it out. The method is getSnapshot, not snapshot

I'm surprised it didn't give me a build error.

For the record, I can confirm that getSnapshot is what is used to show a snapshot of your widget in the Widget Gallery, not getTimeline.
My widgets appear with a Placeholder view in the Widget Gallery
 
 
Q