I have the following iOS widget that works perfectly on the preview panel but does not load (shows the placeholder state) on the simulator.
I have other widgets written almost identically all working perfectly so I'm not sure what's wrong with this one.
import WidgetKit
import AppIntents
import SwiftUI
private let defaultSkiresortDetail = SkiresortDetail(
id: "foobar"
)
private struct SkiresortWidgetIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Ski Resort"
static var description = IntentDescription("Select the ski resort to display.")
@Parameter(title: "Ski Resort")
var skiresort: SkiresortDetail
}
private struct SkiresortQuery: EntityQuery {
func entities(for identifiers: [SkiresortDetail.ID]) -> [SkiresortDetail] {
return [defaultSkiresortDetail]
}
func suggestedEntities() -> [SkiresortDetail] {
[defaultSkiresortDetail]
}
func defaultResult() -> SkiresortDetail? {
suggestedEntities().first
}
}
private struct SkiresortDetail: AppEntity {
let id: String
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Ski Resort"
static var defaultQuery = SkiresortQuery()
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(id)")
}
}
private struct SkiresortWidgetProvider: AppIntentTimelineProvider {
func placeholder(in context: Context) -> SkiresortWidgetTimelineEntry {
return SkiresortWidgetTimelineEntry(date: .now)
}
func snapshot(for configuration: SkiresortWidgetIntent, in context: Context) -> SkiresortWidgetTimelineEntry {
return SkiresortWidgetTimelineEntry(date: .now)
}
func timeline(for configuration: SkiresortWidgetIntent, in context: Context) -> Timeline<SkiresortWidgetTimelineEntry> {
return Timeline(
entries: [
SkiresortWidgetTimelineEntry(date: .now)
],
policy: .atEnd
)
}
}
private struct SkiresortWidgetTimelineEntry: TimelineEntry {
let date: Date
}
private struct SkiresortWidgetView: View {
let entry: SkiresortWidgetTimelineEntry
var body: some View {
Text("Hello")
.font(.title3)
.containerBackground(for: .widget) {}
}
}
struct SkiresortWidget: Widget {
let kind: String = "Skiresort_Status"
var body: some WidgetConfiguration {
AppIntentConfiguration(
kind: kind,
intent: SkiresortWidgetIntent.self,
provider: SkiresortWidgetProvider()
) {
entry in SkiresortWidgetView(entry: entry)
}
.configurationDisplayName("Ski Resort Status")
.description("Your favorite ski resort status at a glance.")
.supportedFamilies([.systemMedium])
}
}
#Preview(as: .systemMedium) {
SkiresortWidget()
} timeline: {
SkiresortWidgetTimelineEntry(date: .now)
}
The widget does not show the "Edit widget" option on long press either.
What am I doing wrong?
I found the problem!
The WidgetConfigurationIntent
must be public, I did mark it as private
.
Xcode will not complain about it or warn you in any way though.