{"id":"7d68c4cc-fe7e-478e-868e-6da69980b910","shortId":"nZBCqD","kind":"skill","title":"Widgetkit","tagline":"Swift Ios Skills skill by Dpearson2699","description":"# WidgetKit and ActivityKit\n\nBuild home screen widgets, Lock Screen widgets, Live Activities, Dynamic Island\npresentations, Control Center controls, and StandBy surfaces for iOS 26+.\n\nSee [references/widgetkit-advanced.md](references/widgetkit-advanced.md) for timeline strategies, push-based\nupdates, Xcode setup, and advanced patterns.\n\n## Contents\n\n- [Workflow](#workflow)\n- [Widget Protocol and WidgetBundle](#widget-protocol-and-widgetbundle)\n- [Configuration Types](#configuration-types)\n- [TimelineProvider](#timelineprovider)\n- [AppIntentTimelineProvider](#appintenttimelineprovider)\n- [Widget Families](#widget-families)\n- [Interactive Widgets (iOS 17+)](#interactive-widgets-ios-17)\n- [Live Activities and Dynamic Island](#live-activities-and-dynamic-island)\n- [Control Center Widgets (iOS 18+)](#control-center-widgets-ios-18)\n- [Lock Screen Widgets](#lock-screen-widgets)\n- [StandBy Mode](#standby-mode)\n- [iOS 26 Additions](#ios-26-additions)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Workflow\n\n### 1. Create a new widget\n\n1. Add a Widget Extension target in Xcode (File > New > Target > Widget Extension).\n2. Enable App Groups for shared data between the app and widget extension.\n3. Define a `TimelineEntry` struct with a `date` property and display data.\n4. Implement a `TimelineProvider` (static) or `AppIntentTimelineProvider` (configurable).\n5. Build the widget view using SwiftUI, adapting layout per `WidgetFamily`.\n6. Declare the `Widget` conforming struct with a configuration and supported families.\n7. Register all widgets in a `WidgetBundle` annotated with `@main`.\n\n### 2. Add a Live Activity\n\n1. Define an `ActivityAttributes` struct with a nested `ContentState`.\n2. Add `NSSupportsLiveActivities = YES` to the app's Info.plist.\n3. Create an `ActivityConfiguration` in the widget bundle with Lock Screen content\n   and Dynamic Island closures.\n4. Start the activity with `Activity.request(attributes:content:pushType:)`.\n5. Update with `activity.update(_:)` and end with `activity.end(_:dismissalPolicy:)`.\n\n### 3. Add a Control Center control\n\n1. Define an `AppIntent` for the action.\n2. Create a `ControlWidgetButton` or `ControlWidgetToggle` in the widget bundle.\n3. Use `StaticControlConfiguration` or `AppIntentControlConfiguration`.\n\n### 4. Review existing widget code\n\nRun through the Review Checklist at the end of this document.\n\n## Widget Protocol and WidgetBundle\n\n### Widget\n\nEvery widget conforms to the `Widget` protocol and returns a `WidgetConfiguration`\nfrom its `body`.\n\n```swift\nstruct OrderStatusWidget: Widget {\n    let kind: String = \"OrderStatusWidget\"\n\n    var body: some WidgetConfiguration {\n        StaticConfiguration(kind: kind, provider: OrderProvider()) { entry in\n            OrderWidgetView(entry: entry)\n        }\n        .configurationDisplayName(\"Order Status\")\n        .description(\"Track your current order.\")\n        .supportedFamilies([.systemSmall, .systemMedium])\n    }\n}\n```\n\n### WidgetBundle\n\nUse `WidgetBundle` to expose multiple widgets from a single extension.\n\n```swift\n@main\nstruct MyAppWidgets: WidgetBundle {\n    var body: some Widget {\n        OrderStatusWidget()\n        FavoritesWidget()\n        DeliveryActivityWidget()   // Live Activity\n        QuickActionControl()       // Control Center\n    }\n}\n```\n\n## Configuration Types\n\nUse `StaticConfiguration` for non-configurable widgets. Use `AppIntentConfiguration`\n(recommended) for configurable widgets paired with `AppIntentTimelineProvider`.\n\n```swift\n// Static\nStaticConfiguration(kind: \"MyWidget\", provider: MyProvider()) { entry in\n    MyWidgetView(entry: entry)\n}\n// Configurable\nAppIntentConfiguration(kind: \"ConfigWidget\", intent: SelectCategoryIntent.self,\n                       provider: CategoryProvider()) { entry in\n    CategoryWidgetView(entry: entry)\n}\n```\n\n### Shared Modifiers\n\n| Modifier | Purpose |\n|---|---|\n| `.configurationDisplayName(_:)` | Name shown in the widget gallery |\n| `.description(_:)` | Description shown in the widget gallery |\n| `.supportedFamilies(_:)` | Array of `WidgetFamily` values |\n| `.supplementalActivityFamilies(_:)` | Live Activity sizes (`.small`, `.medium`) |\n\n## TimelineProvider\n\nFor static (non-configurable) widgets. Uses completion handlers. Three required methods:\n\n```swift\nstruct WeatherProvider: TimelineProvider {\n    typealias Entry = WeatherEntry\n\n    func placeholder(in context: Context) -> WeatherEntry {\n        WeatherEntry(date: .now, temperature: 72, condition: \"Sunny\")\n    }\n\n    func getSnapshot(in context: Context, completion: @escaping (WeatherEntry) -> Void) {\n        let entry = context.isPreview\n            ? placeholder(in: context)\n            : WeatherEntry(date: .now, temperature: currentTemp, condition: currentCondition)\n        completion(entry)\n    }\n\n    func getTimeline(in context: Context, completion: @escaping (Timeline<WeatherEntry>) -> Void) {\n        Task {\n            let weather = await WeatherService.shared.fetch()\n            let entry = WeatherEntry(date: .now, temperature: weather.temp, condition: weather.condition)\n            let nextUpdate = Calendar.current.date(byAdding: .hour, value: 1, to: .now)!\n            completion(Timeline(entries: [entry], policy: .after(nextUpdate)))\n        }\n    }\n}\n```\n\n## AppIntentTimelineProvider\n\nFor configurable widgets. Uses async/await natively. Receives user intent configuration.\n\n```swift\nstruct CategoryProvider: AppIntentTimelineProvider {\n    typealias Entry = CategoryEntry\n    typealias Intent = SelectCategoryIntent\n\n    func placeholder(in context: Context) -> CategoryEntry {\n        CategoryEntry(date: .now, categoryName: \"Sample\", items: [])\n    }\n\n    func snapshot(for config: SelectCategoryIntent, in context: Context) async -> CategoryEntry {\n        let items = await DataStore.shared.items(for: config.category)\n        return CategoryEntry(date: .now, categoryName: config.category.name, items: items)\n    }\n\n    func timeline(for config: SelectCategoryIntent, in context: Context) async -> Timeline<CategoryEntry> {\n        let items = await DataStore.shared.items(for: config.category)\n        let entry = CategoryEntry(date: .now, categoryName: config.category.name, items: items)\n        return Timeline(entries: [entry], policy: .atEnd)\n    }\n}\n```\n\n## Widget Families\n\n### System Families (Home Screen)\n\n| Family | Platform |\n|---|---|\n| `.systemSmall` | iOS, iPadOS, macOS, CarPlay (iOS 26+) |\n| `.systemMedium` | iOS, iPadOS, macOS |\n| `.systemLarge` | iOS, iPadOS, macOS |\n| `.systemExtraLarge` | iPadOS only |\n\n### Accessory Families (Lock Screen / watchOS)\n\n| Family | Platform |\n|---|---|\n| `.accessoryCircular` | iOS, watchOS |\n| `.accessoryRectangular` | iOS, watchOS |\n| `.accessoryInline` | iOS, watchOS |\n| `.accessoryCorner` | watchOS only |\n\nAdapt layout per family using `@Environment(\\.widgetFamily)`:\n\n```swift\n@Environment(\\.widgetFamily) var family\n\nvar body: some View {\n    switch family {\n    case .systemSmall: CompactView(entry: entry)\n    case .systemMedium: DetailedView(entry: entry)\n    case .accessoryCircular: CircularView(entry: entry)\n    default: FullView(entry: entry)\n    }\n}\n```\n\n## Interactive Widgets (iOS 17+)\n\nUse `Button` and `Toggle` with `AppIntent` conforming types to perform actions\ndirectly from a widget without launching the app.\n\n```swift\nstruct ToggleFavoriteIntent: AppIntent {\n    static var title: LocalizedStringResource = \"Toggle Favorite\"\n    @Parameter(title: \"Item ID\") var itemID: String\n\n    func perform() async throws -> some IntentResult {\n        await DataStore.shared.toggleFavorite(itemID)\n        return .result()\n    }\n}\n\nstruct InteractiveWidgetView: View {\n    let entry: FavoriteEntry\n    var body: some View {\n        HStack {\n            Text(entry.itemName)\n            Spacer()\n            Button(intent: ToggleFavoriteIntent(itemID: entry.itemID)) {\n                Image(systemName: entry.isFavorite ? \"star.fill\" : \"star\")\n            }\n        }\n        .padding()\n    }\n}\n```\n\n## Live Activities and Dynamic Island\n\n### ActivityAttributes\n\nDefine the static and dynamic data model.\n\n```swift\nstruct DeliveryAttributes: ActivityAttributes {\n    struct ContentState: Codable, Hashable {\n        var driverName: String\n        var estimatedDeliveryTime: ClosedRange<Date>\n        var currentStep: DeliveryStep\n    }\n\n    var orderNumber: Int\n    var restaurantName: String\n}\n```\n\n### ActivityConfiguration\n\nProvide Lock Screen content and Dynamic Island closures in the widget bundle.\n\n```swift\nstruct DeliveryActivityWidget: Widget {\n    var body: some WidgetConfiguration {\n        ActivityConfiguration(for: DeliveryAttributes.self) { context in\n            VStack(alignment: .leading) {\n                Text(context.attributes.restaurantName).font(.headline)\n                HStack {\n                    Text(\"Driver: \\(context.state.driverName)\")\n                    Spacer()\n                    Text(timerInterval: context.state.estimatedDeliveryTime, countsDown: true)\n                }\n            }\n            .padding()\n        } dynamicIsland: { context in\n            DynamicIsland {\n                DynamicIslandExpandedRegion(.leading) {\n                    Image(systemName: \"box.truck.fill\").font(.title2)\n                }\n                DynamicIslandExpandedRegion(.trailing) {\n                    Text(timerInterval: context.state.estimatedDeliveryTime, countsDown: true)\n                        .font(.caption)\n                }\n                DynamicIslandExpandedRegion(.center) {\n                    Text(context.attributes.restaurantName).font(.headline)\n                }\n                DynamicIslandExpandedRegion(.bottom) {\n                    HStack {\n                        ForEach(DeliveryStep.allCases, id: \\.self) { step in\n                            Image(systemName: step.icon)\n                                .foregroundStyle(step <= context.state.currentStep ? .primary : .tertiary)\n                        }\n                    }\n                }\n            } compactLeading: {\n                Image(systemName: \"box.truck.fill\")\n            } compactTrailing: {\n                Text(timerInterval: context.state.estimatedDeliveryTime, countsDown: true)\n                    .frame(width: 40).monospacedDigit()\n            } minimal: {\n                Image(systemName: \"box.truck.fill\")\n            }\n        }\n    }\n}\n```\n\n### Dynamic Island Regions\n\n| Region | Position |\n|---|---|\n| `.leading` | Left of the TrueDepth camera; wraps below |\n| `.trailing` | Right of the TrueDepth camera; wraps below |\n| `.center` | Directly below the camera |\n| `.bottom` | Below all other regions |\n\n### Starting, Updating, and Ending\n\n```swift\n// Start\nlet attributes = DeliveryAttributes(orderNumber: 123, restaurantName: \"Pizza Place\")\nlet state = DeliveryAttributes.ContentState(\n    driverName: \"Alex\",\n    estimatedDeliveryTime: Date()...Date().addingTimeInterval(1800),\n    currentStep: .preparing\n)\nlet content = ActivityContent(state: state, staleDate: nil, relevanceScore: 75)\nlet activity = try Activity.request(attributes: attributes, content: content, pushType: .token)\n\n// Update (optionally with alert)\nlet updated = ActivityContent(state: newState, staleDate: nil, relevanceScore: 90)\nawait activity.update(updated)\nawait activity.update(updated, alertConfiguration: AlertConfiguration(\n    title: \"Order Update\", body: \"Your driver is nearby!\", sound: .default\n))\n\n// End\nlet final = ActivityContent(state: finalState, staleDate: nil, relevanceScore: 0)\nawait activity.end(final, dismissalPolicy: .after(.now.addingTimeInterval(3600)))\n```\n\n## Control Center Widgets (iOS 18+)\n\n```swift\n// Button control\nstruct OpenCameraControl: ControlWidget {\n    var body: some ControlWidgetConfiguration {\n        StaticControlConfiguration(kind: \"OpenCamera\") {\n            ControlWidgetButton(action: OpenCameraIntent()) {\n                Label(\"Camera\", systemImage: \"camera.fill\")\n            }\n        }\n        .displayName(\"Open Camera\")\n    }\n}\n\n// Toggle control with value provider\nstruct FlashlightControl: ControlWidget {\n    var body: some ControlWidgetConfiguration {\n        StaticControlConfiguration(kind: \"Flashlight\", provider: FlashlightValueProvider()) { value in\n            ControlWidgetToggle(isOn: value, action: ToggleFlashlightIntent()) {\n                Label(\"Flashlight\", systemImage: value ? \"flashlight.on.fill\" : \"flashlight.off.fill\")\n            }\n        }\n        .displayName(\"Flashlight\")\n    }\n}\n```\n\n## Lock Screen Widgets\n\nUse accessory families and `AccessoryWidgetBackground`.\n\n```swift\nstruct StepsWidget: Widget {\n    let kind = \"StepsWidget\"\n    var body: some WidgetConfiguration {\n        StaticConfiguration(kind: kind, provider: StepsProvider()) { entry in\n            ZStack {\n                AccessoryWidgetBackground()\n                VStack {\n                    Image(systemName: \"figure.walk\")\n                    Text(\"\\(entry.stepCount)\").font(.headline)\n                }\n            }\n        }\n        .supportedFamilies([.accessoryCircular, .accessoryRectangular, .accessoryInline])\n    }\n}\n```\n\n## StandBy Mode\n\n`.systemSmall` widgets automatically appear in StandBy (iPhone on charger in\nlandscape). Use `@Environment(\\.widgetLocation)` for conditional rendering:\n\n```swift\n@Environment(\\.widgetLocation) var location\n// location == .standBy, .homeScreen, .lockScreen, .carPlay, etc.\n```\n\n## iOS 26 Additions\n\n### Liquid Glass Support\n\nAdapt widgets to the Liquid Glass visual style using `WidgetAccentedRenderingMode`.\n\n| Mode | Description |\n|---|---|\n| `.accented` | Accented rendering for Liquid Glass |\n| `.accentedDesaturated` | Accented with desaturation |\n| `.desaturated` | Fully desaturated |\n| `.fullColor` | Full-color rendering |\n\n### WidgetPushHandler\n\nEnable push-based timeline reloads without scheduled polling.\n\n```swift\nstruct MyWidgetPushHandler: WidgetPushHandler {\n    func pushTokenDidChange(_ pushInfo: WidgetPushInfo, widgets: [WidgetInfo]) {\n        let tokenString = pushInfo.token.map { String(format: \"%02x\", $0) }.joined()\n        // Send tokenString to your server\n    }\n}\n```\n\n### CarPlay Widgets\n\n`.systemSmall` widgets render in CarPlay on iOS 26+. Ensure small widget layouts\nare legible at a glance for driver safety.\n\n## Common Mistakes\n\n1. **Using IntentTimelineProvider instead of AppIntentTimelineProvider.**\n   `IntentTimelineProvider` is the older SiriKit Intents-based provider. Prefer\n   `AppIntentTimelineProvider` with the App Intents framework for new widgets.\n\n2. **Exceeding the refresh budget.** Widgets have a daily refresh limit. Do not\n   call `WidgetCenter.shared.reloadTimelines(ofKind:)` on every minor data change.\n   Batch updates and use appropriate `TimelineReloadPolicy` values.\n\n3. **Forgetting App Groups for shared data.** The widget extension runs in a\n   separate process. Use `UserDefaults(suiteName:)` or a shared App Group\n   container for data the widget reads.\n\n4. **Performing network calls in placeholder().** `placeholder(in:)` must return\n   synchronously with sample data. Use `getTimeline` or `timeline(for:in:)` for\n   async work.\n\n5. **Missing NSSupportsLiveActivities Info.plist key.** Live Activities will not\n   start without `NSSupportsLiveActivities = YES` in the host app's Info.plist.\n\n6. **Using the deprecated contentState API.** Use `ActivityContent` for all\n   `Activity.request`, `update`, and `end` calls. The `contentState`-based\n   methods are deprecated.\n\n7. **Not handling the stale state.** Check `context.isStale` in Live Activity\n   views and show a fallback (e.g., \"Updating...\") when content is outdated.\n\n8. **Putting heavy logic in the widget view.** Widget views are rendered in a\n   size-limited process. Pre-compute data in the timeline provider and pass\n   display-ready values through the entry.\n\n9. **Ignoring accessory rendering modes.** Lock Screen widgets render in\n   `.vibrant` or `.accented` mode, not `.fullColor`. Test with\n   `@Environment(\\.widgetRenderingMode)` and avoid relying on color alone.\n\n10. **Not testing on device.** Dynamic Island and StandBy behavior differ\n    significantly from Simulator. Always verify on physical hardware.\n\n## Review Checklist\n\n- [ ] Widget extension target has App Groups entitlement matching the main app\n- [ ] `@main` is on the `WidgetBundle`, not on individual widgets\n- [ ] `placeholder(in:)` returns synchronously; `getSnapshot`/`snapshot(for:in:)` fast when `isPreview`\n- [ ] Timeline reload policy matches update frequency; `reloadTimelines(ofKind:)` only on data change\n- [ ] Layout adapts per `WidgetFamily`; accessory widgets tested in `.vibrant` mode\n- [ ] Interactive widgets use `AppIntent` with `Button`/`Toggle` only\n- [ ] Live Activity: `NSSupportsLiveActivities = YES`; `ActivityContent` used; Dynamic Island closures implemented\n- [ ] `activity.end(_:dismissalPolicy:)` called; controls use `StaticControlConfiguration`/`AppIntentControlConfiguration`\n- [ ] Timeline entries and Intent types are Sendable; tested on device\n\n## References\n\n- Advanced guide: [references/widgetkit-advanced.md](references/widgetkit-advanced.md)\n- Apple docs: [WidgetKit](https://sosumi.ai/documentation/widgetkit) | [ActivityKit](https://sosumi.ai/documentation/activitykit) | [Keeping a widget up to date](https://sosumi.ai/documentation/widgetkit/keeping-a-widget-up-to-date)","tags":["widgetkit","swift","ios","skills","dpearson2699"],"capabilities":["skill","source-dpearson2699","category-swift-ios-skills"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/widgetkit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under dpearson2699/swift-ios-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T05:40:38.039Z","embedding":null,"createdAt":"2026-04-18T20:33:35.318Z","updatedAt":"2026-04-22T05:40:38.039Z","lastSeenAt":"2026-04-22T05:40:38.039Z","tsv":"'-26':120 '/documentation/activitykit)':1653 '/documentation/widgetkit)':1649 '/documentation/widgetkit/keeping-a-widget-up-to-date)':1662 '0':1071,1271 '02x':1270 '1':135,140,224,282,558,1302 '10':1530 '123':996 '17':76,81,741 '18':97,103,1083 '1800':1009 '2':153,219,233,289,1327 '26':31,117,670,1210,1287 '3':166,242,276,299,1355 '3600':1078 '4':178,258,304,1384 '40':949 '5':186,267,1407 '6':197,1426 '7':209,1447 '72':502 '75':1020 '8':1469 '9':1504 '90':1043 'accent':1227,1228,1234,1516 'accenteddesatur':1233 'accessori':682,1143,1506,1598 'accessorycircular':689,730,1176 'accessorycorn':698 'accessoryinlin':695,1178 'accessoryrectangular':692,1177 'accessorywidgetbackground':1146,1166 'action':288,752,1098,1129 'activ':19,83,89,223,261,396,468,815,1022,1413,1457,1613 'activity.end':274,1073,1622 'activity.request':263,1024,1436 'activity.update':270,1045,1048 'activityattribut':227,819,830 'activityconfigur':245,850,871 'activitycont':1014,1037,1065,1433,1616 'activitykit':10,1650 'adapt':193,701,1215,1595 'add':141,220,234,277 'addingtimeinterv':1008 'addit':118,121,1211 'advanc':45,1640 'alert':1034 'alertconfigur':1050,1051 'alex':1004 'align':877 'alon':1529 'alway':1544 'annot':216 'api':1431 'app':155,162,239,760,1321,1357,1376,1423,1555,1561 'appear':1184 'appint':285,747,764,1607 'appintentconfigur':410,431 'appintentcontrolconfigur':303,1628 'appintenttimelineprovid':66,67,184,417,568,582,1307,1318 'appl':1644 'appropri':1352 'array':462 'async':609,633,780,1405 'async/await':573 'atend':655 'attribut':264,993,1025,1026 'automat':1183 'avoid':1525 'await':541,613,637,784,1044,1047,1072 'base':40,1249,1315,1443 'batch':1348 'behavior':1539 'bodi':338,348,389,714,796,868,1055,1091,1116,1155 'bottom':921,981 'box.truck.fill':902,940,954 'budget':1331 'build':11,187 'bundl':249,298,862 'button':743,803,1085,1609 'byad':555 'calendar.current.date':554 'call':1340,1387,1440,1624 'camera':965,973,980,1101,1106 'camera.fill':1103 'caption':913 'carplay':668,1207,1278,1284 'case':719,724,729 'category-swift-ios-skills' 'categoryentri':585,594,595,610,618,643 'categorynam':598,621,646 'categoryprovid':437,581 'categorywidgetview':440 'center':24,94,100,280,399,915,976,1080 'chang':1347,1593 'charger':1189 'check':1453 'checklist':128,131,313,1550 'circularview':731 'closedrang':840 'closur':257,858,1620 'codabl':833 'code':308 'color':1243,1528 'common':122,125,1300 'common-mistak':124 'compactlead':937 'compacttrail':941 'compactview':721 'complet':480,510,527,534,561 'comput':1489 'condit':503,525,550,1196 'config':604,628 'config.category':616,640 'config.category.name':622,647 'configur':59,62,185,205,400,407,413,430,477,570,578 'configuration-typ':61 'configurationdisplaynam':361,447 'configwidget':433 'conform':201,327,748 'contain':1378 'content':47,253,265,854,1013,1027,1028,1466 'contentst':232,832,1430,1442 'context':495,496,508,509,519,532,533,592,593,607,608,631,632,874,895 'context.attributes.restaurantname':880,917 'context.ispreview':516 'context.isstale':1454 'context.state.currentstep':934 'context.state.drivername':886 'context.state.estimateddeliverytime':890,909,944 'control':23,25,93,99,279,281,398,1079,1086,1108,1625 'control-center-widgets-io':98 'controlwidget':1089,1114 'controlwidgetbutton':292,1097 'controlwidgetconfigur':1093,1118 'controlwidgettoggl':294,1126 'countsdown':891,910,945 'creat':136,243,290 'current':367 'currentcondit':526 'currentstep':842,1010 'currenttemp':524 'daili':1335 'data':159,177,825,1346,1361,1380,1397,1490,1592 'datastore.shared.items':614,638 'datastore.shared.togglefavorite':785 'date':173,499,521,546,596,619,644,1006,1007,1659 'declar':198 'default':734,1061 'defin':167,225,283,820 'deliveryactivitywidget':394,865 'deliveryattribut':829,994 'deliveryattributes.contentstate':1002 'deliveryattributes.self':873 'deliverystep':843 'deliverystep.allcases':924 'deprec':1429,1446 'desatur':1236,1237,1239 'descript':364,454,455,1226 'detailedview':726 'devic':1534,1638 'differ':1540 'direct':753,977 'dismissalpolici':275,1075,1623 'display':176,1498 'display-readi':1497 'displaynam':1104,1137 'doc':1645 'document':319 'dpearson2699':7 'driver':885,1057,1298 'drivernam':836,1003 'dynam':20,85,91,255,817,824,856,955,1535,1618 'dynamicisland':894,897 'dynamicislandexpandedregion':898,905,914,920 'e.g':1463 'enabl':154,1246 'end':272,316,989,1062,1439 'ensur':1288 'entitl':1557 'entri':356,359,360,425,428,429,438,441,442,490,515,528,544,563,564,584,642,652,653,722,723,727,728,732,733,736,737,793,1163,1503,1630 'entry.isfavorite':810 'entry.itemid':807 'entry.itemname':801 'entry.stepcount':1172 'environ':706,709,1193,1199,1522 'escap':511,535 'estimateddeliverytim':839,1005 'etc':1208 'everi':325,1344 'exceed':1328 'exist':306 'expos':376 'extens':144,152,165,382,1364,1552 'fallback':1462 'famili':69,72,208,657,659,662,683,687,704,712,718,1144 'fast':1579 'favorit':770 'favoriteentri':794 'favoriteswidget':393 'figure.walk':1170 'file':148 'final':1064,1074 'finalst':1067 'flashlight':1121,1132,1138 'flashlight.off.fill':1136 'flashlight.on.fill':1135 'flashlightcontrol':1113 'flashlightvalueprovid':1123 'font':881,903,912,918,1173 'foreach':923 'foregroundstyl':932 'forget':1356 'format':1269 'frame':947 'framework':1323 'frequenc':1587 'full':1242 'full-color':1241 'fullcolor':1240,1519 'fulli':1238 'fullview':735 'func':492,505,529,589,601,625,778,1259 'galleri':453,460 'getsnapshot':506,1575 'gettimelin':530,1399 'glanc':1296 'glass':1213,1220,1232 'group':156,1358,1377,1556 'guid':1641 'handl':1449 'handler':481 'hardwar':1548 'hashabl':834 'headlin':882,919,1174 'heavi':1471 'home':12,660 'homescreen':1205 'host':1422 'hour':556 'hstack':799,883,922 'id':774,925 'ignor':1505 'imag':808,900,929,938,952,1168 'implement':179,1621 'individu':1569 'info.plist':241,1410,1425 'instead':1305 'int':846 'intent':434,577,587,804,1314,1322,1632 'intentresult':783 'intents-bas':1313 'intenttimelineprovid':1304,1308 'interact':73,78,738,1604 'interactive-widgets-io':77 'interactivewidgetview':790 'io':3,30,75,80,96,102,116,119,665,669,672,676,690,693,696,740,1082,1209,1286 'ipado':666,673,677,680 'iphon':1187 'island':21,86,92,256,818,857,956,1536,1619 'ison':1127 'ispreview':1581 'item':600,612,623,624,636,648,649,773 'itemid':776,786,806 'join':1272 'keep':1654 'key':1411 'kind':344,352,353,421,432,1095,1120,1152,1159,1160 'label':1100,1131 'landscap':1191 'launch':758 'layout':194,702,1291,1594 'lead':878,899,960 'left':961 'legibl':1293 'let':343,514,539,543,552,611,635,641,792,992,1000,1012,1021,1035,1063,1151,1265 'limit':1337,1485 'liquid':1212,1219,1231 'live':18,82,88,222,395,467,814,1412,1456,1612 'live-activities-and-dynamic-island':87 'localizedstringresourc':768 'locat':1202,1203 'lock':15,104,108,251,684,852,1139,1509 'lock-screen-widget':107 'lockscreen':1206 'logic':1472 'maco':667,674,678 'main':218,384,1560,1562 'match':1558,1585 'medium':471 'method':484,1444 'minim':951 'minor':1345 'miss':1408 'mistak':123,126,1301 'mode':112,115,1180,1225,1508,1517,1603 'model':826 'modifi':444,445 'monospaceddigit':950 'multipl':377 'must':1392 'myappwidget':386 'myprovid':424 'mywidget':422 'mywidgetpushhandl':1257 'mywidgetview':427 'name':448 'nativ':574 'nearbi':1059 'nest':231 'network':1386 'new':138,149,1325 'newstat':1039 'nextupd':553,567 'nil':1018,1041,1069 'non':406,476 'non-configur':405,475 'now.addingtimeinterval':1077 'nssupportsliveact':235,1409,1418,1614 'ofkind':1342,1589 'older':1311 'open':1105 'opencamera':1096 'opencameracontrol':1088 'opencameraint':1099 'option':1032 'order':362,368,1053 'ordernumb':845,995 'orderprovid':355 'orderstatuswidget':341,346,392 'orderwidgetview':358 'outdat':1468 'pad':813,893 'pair':415 'paramet':771 'pass':1496 'pattern':46 'per':195,703,1596 'perform':751,779,1385 'physic':1547 'pizza':998 'place':999 'placehold':493,517,590,1389,1390,1571 'platform':663,688 'polici':565,654,1584 'poll':1254 'posit':959 'pre':1488 'pre-comput':1487 'prefer':1317 'prepar':1011 'present':22 'primari':935 'process':1369,1486 'properti':174 'protocol':51,56,321,331 'provid':354,423,436,851,1111,1122,1161,1316,1494 'purpos':446 'push':39,1248 'push-bas':38,1247 'pushinfo':1261 'pushinfo.token.map':1267 'pushtokendidchang':1260 'pushtyp':266,1029 'put':1470 'quickactioncontrol':397 'read':1383 'readi':1499 'receiv':575 'recommend':411 'refer':132,133,1639 'references/widgetkit-advanced.md':33,34,1642,1643 'refresh':1330,1336 'region':957,958,985 'regist':210 'relevancescor':1019,1042,1070 'reli':1526 'reload':1251,1583 'reloadtimelin':1588 'render':1197,1229,1244,1282,1480,1507,1512 'requir':483 'restaurantnam':848,997 'result':788 'return':333,617,650,787,1393,1573 'review':127,130,305,312,1549 'review-checklist':129 'right':969 'run':309,1365 'safeti':1299 'sampl':599,1396 'schedul':1253 'screen':13,16,105,109,252,661,685,853,1140,1510 'see':32 'selectcategoryint':588,605,629 'selectcategoryintent.self':435 'self':926 'send':1273 'sendabl':1635 'separ':1368 'server':1277 'setup':43 'share':158,443,1360,1375 'show':1460 'shown':449,456 'signific':1541 'simul':1543 'singl':381 'sirikit':1312 'size':469,1484 'size-limit':1483 'skill':4,5 'small':470,1289 'snapshot':602,1576 'sosumi.ai':1648,1652,1661 'sosumi.ai/documentation/activitykit)':1651 'sosumi.ai/documentation/widgetkit)':1647 'sosumi.ai/documentation/widgetkit/keeping-a-widget-up-to-date)':1660 'sound':1060 'source-dpearson2699' 'spacer':802,887 'stale':1451 'staled':1017,1040,1068 'standbi':27,111,114,1179,1186,1204,1538 'standby-mod':113 'star':812 'star.fill':811 'start':259,986,991,1416 'state':1001,1015,1016,1038,1066,1452 'static':182,419,474,765,822 'staticconfigur':351,403,420,1158 'staticcontrolconfigur':301,1094,1119,1627 'status':363 'step':927,933 'step.icon':931 'stepsprovid':1162 'stepswidget':1149,1153 'strategi':37 'string':345,777,837,849,1268 'struct':170,202,228,340,385,486,580,762,789,828,831,864,1087,1112,1148,1256 'style':1222 'suitenam':1372 'sunni':504 'supplementalactivityfamili':466 'support':207,1214 'supportedfamili':369,461,1175 'surfac':28 'swift':2,339,383,418,485,579,708,761,827,863,990,1084,1147,1198,1255 'swiftui':192 'switch':717 'synchron':1394,1574 'system':658 'systemextralarg':679 'systemimag':1102,1133 'systemlarg':675 'systemmedium':371,671,725 'systemnam':809,901,930,939,953,1169 'systemsmal':370,664,720,1181,1280 'target':145,150,1553 'task':538 'temperatur':501,523,548 'tertiari':936 'test':1520,1532,1600,1636 'text':800,879,884,888,907,916,942,1171 'three':482 'throw':781 'timelin':36,536,562,626,634,651,1250,1401,1493,1582,1629 'timelineentri':169 'timelineprovid':64,65,181,472,488 'timelinereloadpolici':1353 'timerinterv':889,908,943 'titl':767,772,1052 'title2':904 'toggl':745,769,1107,1610 'togglefavoriteint':763,805 'toggleflashlightint':1130 'token':1030 'tokenstr':1266,1274 'track':365 'trail':906,968 'tri':1023 'true':892,911,946 'truedepth':964,972 'type':60,63,401,749,1633 'typealia':489,583,586 'updat':41,268,987,1031,1036,1046,1049,1054,1349,1437,1464,1586 'use':191,300,373,402,409,479,572,705,742,1142,1192,1223,1303,1351,1370,1398,1427,1432,1606,1617,1626 'user':576 'userdefault':1371 'valu':465,557,1110,1124,1128,1134,1354,1500 'var':347,388,711,713,766,775,795,835,838,841,844,847,867,1090,1115,1154,1201 'verifi':1545 'vibrant':1514,1602 'view':190,716,791,798,1458,1476,1478 'visual':1221 'void':513,537 'vstack':876,1167 'watcho':686,691,694,697,699 'weather':540 'weather.condition':551 'weather.temp':549 'weatherentri':491,497,498,512,520,545 'weatherprovid':487 'weatherservice.shared.fetch':542 'widget':14,17,50,55,68,71,74,79,95,101,106,110,139,143,151,164,189,200,212,248,297,307,320,324,326,330,342,378,391,408,414,452,459,478,571,656,739,756,861,866,1081,1141,1150,1182,1216,1263,1279,1281,1290,1326,1332,1363,1382,1475,1477,1511,1551,1570,1599,1605,1656 'widget-famili':70 'widget-protocol-and-widgetbundl':54 'widgetaccentedrenderingmod':1224 'widgetbundl':53,58,215,323,372,374,387,1566 'widgetcenter.shared.reloadtimelines':1341 'widgetconfigur':335,350,870,1157 'widgetfamili':196,464,707,710,1597 'widgetinfo':1264 'widgetkit':1,8,1646 'widgetloc':1194,1200 'widgetpushhandl':1245,1258 'widgetpushinfo':1262 'widgetrenderingmod':1523 'width':948 'without':757,1252,1417 'work':1406 'workflow':48,49,134 'wrap':966,974 'xcode':42,147 'yes':236,1419,1615 'zstack':1165","prices":[{"id":"cdc49fbd-5c49-49fe-8087-4dcd8fc58f06","listingId":"7d68c4cc-fe7e-478e-868e-6da69980b910","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:33:35.318Z"}],"sources":[{"listingId":"7d68c4cc-fe7e-478e-868e-6da69980b910","source":"github","sourceId":"dpearson2699/swift-ios-skills/widgetkit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/widgetkit","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:32.339Z","lastSeenAt":"2026-04-22T00:53:46.097Z"},{"listingId":"7d68c4cc-fe7e-478e-868e-6da69980b910","source":"skills_sh","sourceId":"dpearson2699/swift-ios-skills/widgetkit","sourceUrl":"https://skills.sh/dpearson2699/swift-ios-skills/widgetkit","isPrimary":true,"firstSeenAt":"2026-04-18T20:33:35.318Z","lastSeenAt":"2026-04-22T05:40:38.039Z"}],"details":{"listingId":"7d68c4cc-fe7e-478e-868e-6da69980b910","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"widgetkit","source":"skills_sh","category":"swift-ios-skills","skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/widgetkit"},"updatedAt":"2026-04-22T05:40:38.039Z"}}