iOS app with Home Screen and Lock Screen widgets written in Swift/SwiftUI. I've never been able to get widgets to work properly. It's more pronounced on Lock Screen widgets, so let's try that method first...
The app stores data in Core Data as an Event
. They're read into my model and stored as WidgetEventDetails
structs:
struct WidgetEventDetails: AppEntity, Identifiable, Hashable {
public var eventId: String
public var name: String
public var date: Date
public var id: String {
eventId
}
This all works absolutely fine in the iOS app, and each one is unique based on the eventId
.
When I go to add a Lock Screen widget, I customise the Lock Screen, tap in the section to add a widget, and my widgets appear correctly and are selectable: (bottom right, says "1y 28w 1d")
So, I tap it and it appears in the widgets section:
But it appears as "17w 6d", which is a different event entirely. Notice how the one in the selectable widgets has changed to "15w 5d", and the one I tapped (1y 28w 1d) is nowhere to be seen.
So, I tap the one in the top row (17w 6d) to select an event, and this appears, suggesting that the event is the "Edinburgh & Glasgow 2024-02" event:
But that event is actually only a day away (1d), so that's not the one I selected at all.
I tap the list and see these events:
I select "Las Vegas 2024", which is 17w 3d away, and this is shown:
17w 6d is a different event, not Las Vegas 2024.
So, I tap it again and see this. The "Loading" text appears for ages, but occasionally does show the full list, as before:
I select "Edinburgh & Glasgow 2024-02" which is 1d away, and I see this again:
So, I resign myself to hoping it'll just figure itself out, and I tap "Done":
"17w 6d" again :(
I finish customising, and exit the customisation screen. I show the Lock Screen, and I see this:
Why doesn't this work?
Here's the code:
@main
struct WidgetExtensionBundle: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
WidgetExtension()
}
}
struct WidgetExtension: Widget {
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kWidgetKind, intent: WidgetEventIntent.self, provider: WidgetEventTimelineProvider()) { entry in
WidgetEntry(entry: entry)
.environment(modelData)
}
.configurationDisplayName(NSLocalizedString("AddingWidget_Title", comment: "Adding the Widget"))
.description(NSLocalizedString("AddingWidget_Description", comment: "Adding the Widget"))
.supportedFamilies([.accessoryCircular, .accessoryInline, .accessoryRectangular, .systemSmall, .systemMedium])
.contentMarginsDisabled()
}
}
struct WidgetEventIntent: WidgetConfigurationIntent {
static let title: LocalizedStringResource = "AddingWidget_Title"
static let description = IntentDescription(LocalizedStringResource("AddingWidget_Description"))
@Parameter(title: LocalizedStringResource("Event"))
var event: WidgetEventDetails?
init(event: WidgetEventDetails? = nil) {
self.event = event
}
init() {}
static var parameterSummary: some ParameterSummary {
Summary {
\.$event
}
}
}
struct EventQuery: EntityQuery, Sendable {
func entities(for identifiers: [WidgetEventDetails.ID]) async throws -> [WidgetEventDetails] {
modelData.availableEvents.filter { identifiers.contains($0.id) } // availableEvents is just [WidgetEventDetails]
}
func suggestedEntities() async throws -> [WidgetEventDetails] {
return modelData.availableEvents.filter { $0.type == kEventTypeStandard }
}
}
If you think it's the TimelineProvider causing it, I can provide that code, too.
I'd really appreciate some help here, guys. Anyone from Apple able to chip in and tell me where I'm going wrong? Other apps have widgets working fine, so I must be screwing this up somehow? Sadly, none of the sample code provided by Apple is of any use. Whatever I try just doesn't work.
Sorry to be so negative, but a massive company like Apple should be able to see what's wrong and suggest a fix, surely?
Do I have to use one of my support incidents and waste the first 30 minutes confirming my day is going well, thank you very much?