widgetkit▌
dpearson2699/swift-ios-skills · updated Apr 8, 2026
$22
WidgetKit and ActivityKit
Build home screen widgets, Lock Screen widgets, Live Activities, Dynamic Island presentations, Control Center controls, and StandBy surfaces for iOS 26+.
See references/widgetkit-advanced.md for timeline strategies, push-based updates, Xcode setup, and advanced patterns.
Contents
- Workflow
- Widget Protocol and WidgetBundle
- Configuration Types
- TimelineProvider
- AppIntentTimelineProvider
- Widget Families
- Interactive Widgets (iOS 17+)
- Live Activities and Dynamic Island
- Control Center Widgets (iOS 18+)
- Lock Screen Widgets
- StandBy Mode
- iOS 26 Additions
- Common Mistakes
- Review Checklist
- References
Workflow
1. Create a new widget
- Add a Widget Extension target in Xcode (File > New > Target > Widget Extension).
- Enable App Groups for shared data between the app and widget extension.
- Define a
TimelineEntrystruct with adateproperty and display data. - Implement a
TimelineProvider(static) orAppIntentTimelineProvider(configurable). - Build the widget view using SwiftUI, adapting layout per
WidgetFamily. - Declare the
Widgetconforming struct with a configuration and supported families. - Register all widgets in a
WidgetBundleannotated with@main.
2. Add a Live Activity
- Define an
ActivityAttributesstruct with a nestedContentState. - Add
NSSupportsLiveActivities = YESto the app's Info.plist. - Create an
ActivityConfigurationin the widget bundle with Lock Screen content and Dynamic Island closures. - Start the activity with
Activity.request(attributes:content:pushType:). - Update with
activity.update(_:)and end withactivity.end(_:dismissalPolicy:).
3. Add a Control Center control
- Define an
AppIntentfor the action. - Create a
ControlWidgetButtonorControlWidgetTogglein the widget bundle. - Use
StaticControlConfigurationorAppIntentControlConfiguration.
4. Review existing widget code
Run through the Review Checklist at the end of this document.
Widget Protocol and WidgetBundle
Widget
Every widget conforms to the Widget protocol and returns a WidgetConfiguration
from its body.
struct OrderStatusWidget: Widget {
let kind: String = "OrderStatusWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: OrderProvider()) { entry in
OrderWidgetView(entry: entry)
}
.configurationDisplayName("Order Status")
.description("Track your current order.")
.supportedFamilies([.systemSmall, .systemMedium])
}
}
WidgetBundle
Use WidgetBundle to expose multiple widgets from a single extension.
@main
struct MyAppWidgets: WidgetBundle {
var body: some Widget {
OrderStatusWidget()
FavoritesWidget()
DeliveryActivityWidget() // Live Activity
QuickActionControl() // Control Center
}
}
Configuration Types
Use StaticConfiguration for non-configurable widgets. Use AppIntentConfiguration
(recommended) for configurable widgets paired with AppIntentTimelineProvider.
// Static
StaticConfiguration(kind: "MyWidget", provider: MyProvider()) { entry in
MyWidgetView(entry: entry)
}
// Configurable
AppIntentConfiguration(kind: "ConfigWidget", intent: SelectCategoryIntent.self,
provider: CategoryProvider()) { entry in
CategoryWidgetView(entry: entry)
}
Shared Modifiers
| Modifier | Purpose |
|---|---|
.configurationDisplayName(_:) |
Name shown in the widget gallery |
.description(_:) |
Description shown in the widget gallery |
.supportedFamilies(_:) |
Array of WidgetFamily values |
.supplementalActivityFamilies(_:) |
Live Activity sizes (.small, .medium) |
TimelineProvider
For static (non-configurable) widgets. Uses completion handlers. Three required methods:
struct WeatherProvider: TimelineProvider {
typealias Entry = WeatherEntry
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: .now, temperature: 72, condition: "Sunny")
}
func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {
let entry = context.isPreview
? placeholder(in: context)
: WeatherEntry(date: .now, temperature: currentTemp, condition: currentCondition)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {
Task {
let weather = await WeatherService.shared.fetch()
let entry = WeatherEntry(date: .now, temperature: weather.temp, condition: weather.condition)
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 1, to: .now)!
completion(Timeline(entries: [entry], policy: .after(nextUpdate)))
}
}
}
AppIntentTimelineProvider
For configurable widgets. Uses async/await natively. Receives user intent configuration.
struct CategoryProvider: AppIntentTimelineProvider {
typealias Entry = CategoryEntry
typealias Intent = SelectCategoryIntent
func placeholder(in context: Context) -> CategoryEntry {
CategoryEntry(date: .now, categoryName: "Sample", items: [])
}
func snapshot(for config: SelectCategoryIntent, in context: Context) async -> CategoryEntry {
let items = await DataStore.shared.items(for: config.category)
return CategoryEntry(date: .now, categoryName: config.category.name, items: items)
}
func timeline(for config: SelectCategoryIntentDiscussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.7★★★★★66 reviews- ★★★★★Shikha Mishra· Dec 28, 2024
Registry listing for widgetkit matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Nia Bhatia· Dec 28, 2024
Useful defaults in widgetkit — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Henry Farah· Dec 16, 2024
Registry listing for widgetkit matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Harper Desai· Dec 4, 2024
We added widgetkit from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
- ★★★★★Camila Gonzalez· Dec 4, 2024
I recommend widgetkit for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Anika Kapoor· Nov 23, 2024
widgetkit fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
- ★★★★★Luis Reddy· Nov 23, 2024
Useful defaults in widgetkit — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Rahul Santra· Nov 19, 2024
Keeps context tight: widgetkit is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Daniel Robinson· Nov 19, 2024
I recommend widgetkit for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Chen Rahman· Nov 7, 2024
Keeps context tight: widgetkit is the kind of skill you can hand to a new teammate without a long onboarding doc.
showing 1-10 of 66