Configurable Widgets: iOS

Rajesh Budhiraja
2 min readSep 24, 2023

We have created static widgets in the given article:

Static widgets are widgets that the user can’t modify. For this example, we will create a widget where the user can select the photo from one of the many photos.

Let’s create Intent now.

Intent conforms to WidgetConfigurationIntent protocol. The parameter is what the user will configure while editing the widget. We will see how it works soon.

struct TestWidgetConfigurationIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Events"
static var description: IntentDescription? = "Choose Events"

@Parameter(title: "Events")
var event: EventAppIntent
}
struct EventAppIntent: AppEntity {
var id: String
var event: Event

static var typeDisplayRepresentation: TypeDisplayRepresentation = "Choose Event"
static var defaultQuery = EventQuery()

var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(event.name)")
}
}

EventQuery decides how the list is populated, the default item. Here, we can fetch data from API, SwiftData, CoreData, or something else. Since we are using SwiftData, we will see how to fetch data using that.

import AppIntents
import SwiftData

struct EventQuery: EntityQuery {

func entities(for identifiers: [EventAppIntent.ID]) async throws -> [EventAppIntent] {
await fetchEventIntents()
}

func suggestedEntities() async throws -> [EventAppIntent] {
await fetchEventIntents()
}

func defaultResult() async -> EventAppIntent? {
await fetchEventIntents().first
}

private func fetchEventIntents() async -> [EventAppIntent] {
var eventsAppIntents: [EventAppIntent] = []
let events = await fetchEvents()
for event in events {
eventsAppIntents.append(.init(id: event.eventId, event: event))
}
return eventsAppIntents
}

@MainActor
private func fetchEvents() -> [Event] {
guard let modelContainer = try? ModelContainer(for: Event.self) else {
return []
}
let descriptor = FetchDescriptor<Event>()
guard…

--

--