Skills Plugins MCP Prompt Model 博客 我的中心

widgetkit

Implement, review, or improve WidgetKit widgets and controls. Use when building Home Screen, Lock Screen, StandBy, or CarPlay widgets with timeline providers; configurable widgets with AppIntentTimelineProvider; interactive widgets or Control Center controls with Button/Toggle wiring; WidgetKit push reloads, refresh budgets, deep links, Smart Stack relevance, Liquid Glass/accented rendering, widget extension setup, WidgetBundle, App Groups, and entitlements.

DeepseekModel 官方收录技能 质量 优秀 · 90 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=dpearson2699-swift-ios-skills-skills-widgetkit-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name widgetkit description Implement, review, or improve WidgetKit widgets and controls. Use when building Home Screen, Lock Screen, StandBy, or CarPlay widgets with timeline providers; configurable widgets with AppIntentTimelineProvider; interactive widgets or Control Center controls with Button/Toggle wiring; WidgetKit push reloads, refresh budgets, deep links, Smart Stack relevance, Liquid Glass/accented rendering, widget extension setup, WidgetBundle, App Groups, and entitlements. WidgetKit Build home screen widgets, Lock Screen widgets, Control Center controls, and StandBy or CarPlay widget surfaces for iOS 26+. Keep adjacent-framework guidance scoped to WidgetKit integration. Include ActivityKit and App Intents only where they connect directly to WidgetKit surfaces; hand off full lifecycle, APNs content-state, Siri/Shortcuts/Spotlight, or entity-modeling work to sibling activitykit or app-intents skills. 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+) ActivityConfiguration Handoff Control Center Widgets (iOS 18+) Lock Screen Widgets StandBy Mode Widget URL Handling and Deep Links Smart Stack Relevance Design Patterns 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 TimelineEntry struct with a date property and display data. Implement a TimelineProvider (static) or AppIntentTimelineProvider (configurable). Build the widget view using SwiftUI, adapting layout per WidgetFamily . Declare the Widget conforming struct with a configuration and supported families. Register all widgets in a WidgetBundle annotated with @main . 2. Integrate adjacent surfaces Register an ActivityConfiguration in the widget bundle when the app has a Live Activity, but keep ActivityAttributes , request/update/end, APNs content-state , and Dynamic Island layout depth in activitykit . Place Button , Toggle , ControlWidgetButton , and ControlWidgetToggle in WidgetKit views or controls, but keep intent modeling, entities, queries, Siri, Shortcuts, and Spotlight in app-intents . 3. Add a Control Center control Reuse an AppIntent / OpenIntent for a button, or a SetValueIntent for a toggle. Create a ControlWidgetButton or ControlWidgetToggle in the widget bundle. Use StaticControlConfiguration or AppIntentControlConfiguration . 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 () // ActivityConfiguration handoff 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 : SelectCategoryIntent , in context : Context ) async -> Timeline < CategoryEntry > { let items = await DataStore .shared.items(for: config.category) let entry = CategoryEntry (date: .now, categoryName: config.category.name, items: items) return Timeline (entries: [entry], policy: .atEnd) } } Widget Families Family Platform .systemSmall iOS, iPadOS, macOS, CarPlay (iOS 26+) .systemMedium iOS, iPadOS, macOS .systemLarge iOS, iPadOS, macOS .systemExtraLarge iPadOS only .accessoryCircular iOS, watchOS .accessoryRectangular iOS, watchOS .accessoryInline iOS, watchOS .accessoryCorner watchOS only Adapt layout per family using @Environment(\.widgetFamily) : @Environment (\.widgetFamily) var family var body: some View { switch family { case .systemSmall: CompactView (entry: entry) case .systemMedium: DetailedView (entry: entry) case .accessoryCircular: CircularView (entry: entry) default : FullView (entry: entry) } } Interactive Widgets (iOS 17+) Use Button and Toggle with intent types available to the widget extension or shared code. WidgetKit owns the view placement; app-intents owns intent modeling and behavior. struct InteractiveWidgetView : View { let entry: FavoriteEntry var body: some View { Button (intent: ToggleFavoriteIntent (itemID: entry.itemID)) { Image (systemName: entry.isFavorite ? "star.fill" : "star" ) } } } ActivityConfiguration Handoff WidgetKit registers Live Activity surfaces in the widget extension. Keep this section to registration and rendering handoff; use activitykit for ActivityAttributes , lifecycle, push updates, and full Dynamic Island patterns. struct DeliveryActivityWidget : Widget { var body: some WidgetConfiguration { ActivityConfiguration (for: DeliveryAttributes . self ) { context in DeliveryLiveActivityView (context: context) } dynamicIsland: { context in DeliveryDynamicIsland (context: context) } } } Control Center Widgets (iOS 18+) WidgetKit owns control configuration, placement, kind, display name, push handler, and extension registration. Control actions and value intents belong in app-intents . struct OpenCameraControl : ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration (kind: "OpenCamera" ) { ControlWidgetButton (action: OpenCameraIntent ()) { Label ( "Camera" , systemImage: "camera.fill" ) } } .displayName( "Open Camera" ) } } struct FlashlightControl : ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration (kind: "Flashlight" , provider: FlashlightValueProvider ()) { value in ControlWidgetToggle (isOn: value, action: ToggleFlashlightIntent ()) { Label ( "Flashlight" , systemImage: value ? "flashlight.on.fill" : "flashlight.off.fill" ) } } .displayName( "Flashlight" ) } } Lock Screen Widgets Use accessory families and AccessoryWidgetBackground . struct StepsWidget : Widget { let kind = "StepsWidget" var body: some WidgetConfiguration { StaticConfiguration (kind: kind, provider: StepsProvider ()) { entry in ZStack { AccessoryWidgetBackground () VStack { Image (systemName: "figure.walk" ) Text ( " \(entry.stepCount) " ).font(.headline) } } } .supportedFamilies([.accessoryCircular, .accessoryRectangular, .accessoryInline]) } } StandBy Mode Small system widgets can appear in StandBy and CarPlay. Use @Environment(\.widgetLocation) for conditional rendering: @Environment (\.widgetLocation) var location // location == .standBy, .homeScreen, .lockScreen, .carPlay, etc. Widget URL Handling and Deep Links Use one .widgetURL(_:) as the whole-widget fallback route. Use Link for deliberate subtargets only where the family and layout support them, including .accessoryRectangular , .systemSmall , and larger system widgets. For small widgets, prefer one clear fallback; avoid multiple Link targets unless the visual affordance and hit areas remain unambiguous. Never attach multiple widgetURL modifiers in the hierarchy. Smart Stack Relevance Use TimelineEntryRelevance(score:duration:) on timeline entries for timely iPhone and iPad Smart Stack relevance. Keep scores on a consistent positive scale; zero or lower means not relevant. For configurable widgets, donate App Intents that correspond to user actions or widget parameters from app-side code, such as with intent.donate() or IntentDonationManager . Keep AppEntity and EntityQuery design in app-intents . On watchOS, contextual relevance uses WidgetRelevance([WidgetRelevanceAttribute(...)]) from the provider relevance() callback. That path is not used by iPhone or iPad Smart Stacks. Design Patterns Prefer Gauge over manual arcs. Use .gaugeStyle(.accessoryCircular) for Lock Screen circular widgets and .linearCapacity for home screen capacity bars. The system handles styling, accessibility, and rendering-mode adaptation. Use .containerBackground(_:for: .widget) (iOS 17+) for widget backgrounds instead of padding and background modifiers. Use Canvas for dense visualizations like sparklines or mini bar charts. The lack of per-element accessibility is acceptable since the entire widget surface is a single tap target. Match timeline refresh to data granularity. The budget is dynamic and opportunistic; schedule useful future entries, avoid unnecessary reloads, and use Text(timerInterval:countsDown:) for live countdowns. Load the advanced reference for current budget guidance. See references/widgetkit-advanced.md for code examples and detailed guidance on each pattern. iOS 26 Additions Liquid Glass Support Adapt widgets to Liquid Glass with @Environment(\.widgetRenderingMode) , .widgetAccentable() , and Image.widgetAccentedRenderingMode(_:) . In .vibrant , the system maps content into the material style, so avoid relying on original colors alone. Push Reload Handlers Widget push reloads: Add Push Notifications capability to the widget extension target. Keep the WidgetPushHandler type in the widget extension target or shared code linked into it, not only in the main app target. Register the handler with .pushHandler(...) on the widget configuration. Do not use User Notifications registration to obtain widget push tokens; WidgetKit supplies tokens through pushTokenDidChange(_:widgets:) . Use apns-push-type: widgets , topic suffix .push-type.widgets , and aps.content-changed . Treat push as a budgeted, opportunistic reload signal, not state delivery and not the only freshness model. Timelines, reload policies, shared storage or refetch, and app-triggered WidgetCenter reloads remain the fallback path. Control push reloads: Register a ControlPushHandler with .pushHandler(...) on the ControlWidgetConfiguration . pushTokensDidChange(controls:) receives [ControlInfo] ; read tokens from each control's pushInfo . Use apns-push-type: controls , topic suffix .push-type.controls , and aps.content-changed . CarPlay Widgets Small system widgets can appear in CarPlay on iOS 26+. Ensure layouts are legible at a glance; taps and controls depend on vehicle touch support and, for opening the app, CarPlay integration. Common Mistakes Using IntentTimelineProvider instead of AppIntentTimelineProvider. IntentTimelineProvider is the older SiriKit Intents-based provider. Prefer AppIntentTimelineProvider with the App Intents framework for new widgets. Exceeding the refresh budget. Widgets have a daily refresh limit. Do not call WidgetCenter.shared.reloadTimelines(ofKind:) on every minor data change. Batch updates and use appropriate TimelineReloadPolicy values. Forgetting App Groups for shared data. The widget extension runs in a separate process. Use UserDefaults(suiteName:) or a shared App Group container for data the widget reads. Performing network calls in placeholder(). placeholder(in:) must return synchronously with sample data. Use getTimeline or timeline(for:in:) for async work. Treating WidgetKit push payloads as state. Widget and control pushes are reload signals. Persist state in shared storage or refetch it in the provider. Registering widget pushes through User Notifications. Widget push tokens come from WidgetKit handlers, not UNUserNotificationCenter . Putting heavy logic in the widget view. Widget views are rendered in a size-limited process. Pre-compute data in the timeline provider and pass display-ready values through the entry. Ignoring accessory rendering modes. Lock Screen widgets render in .vibrant or .accented mode, not .fullColor . Test with @Environment(\.widgetRenderingMode) and avoid relying on color alone. Not testing on device. StandBy, CarPlay, and accessory rendering differ
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。