swiftship/internal/skills/data/watchos/widgets/SKILL.md
watchOS complications: WidgetKit complication families, accessory sizes, timeline providers for watch face. Use when implementing watchOS-specific patterns related to widgets.
npx skillsauth add abdullah4ai/apple-dev-docs widgetsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
WATCH COMPLICATIONS (WidgetKit):
COMPLICATION FAMILIES:
| Family | Shape | Use Case |
|--------|-------|----------|
| .accessoryCircular | Small circle | Single metric, icon + value |
| .accessoryRectangular | Rectangle | Multi-line text, small chart |
| .accessoryInline | Single line text | Short status text on watch face |
| .accessoryCorner | Corner gauge | Gauge with label |
TIMELINE PROVIDER:
struct ComplicationProvider: TimelineProvider {
func placeholder(in context: Context) -> ComplicationEntry {
ComplicationEntry(date: .now, value: 0, label: "—")
}
func getSnapshot(in context: Context, completion: @escaping (ComplicationEntry) -> Void) {
completion(ComplicationEntry(date: .now, value: 42, label: "Steps"))
}
func getTimeline(in context: Context, completion: @escaping (Timeline<ComplicationEntry>) -> Void) {
let entry = ComplicationEntry(date: .now, value: 42, label: "Steps")
let timeline = Timeline(entries: [entry], policy: .after(.now.addingTimeInterval(900)))
completion(timeline)
}
}
struct ComplicationEntry: TimelineEntry {
let date: Date
let value: Int
let label: String
}
COMPLICATION VIEWS:
struct ComplicationView: View {
var entry: ComplicationProvider.Entry
@Environment(\.widgetFamily) var family
var body: some View {
switch family {
case .accessoryCircular:
Gauge(value: Double(entry.value), in: 0...100) {
Text(entry.label)
}
.gaugeStyle(.accessoryCircularCapacity)
case .accessoryRectangular:
VStack(alignment: .leading) {
Text(entry.label)
.font(AppTheme.Fonts.headline)
.widgetAccentable()
Text("\(entry.value)")
.font(AppTheme.Fonts.title2)
}
case .accessoryInline:
Text("\(entry.label): \(entry.value)")
case .accessoryCorner:
Text("\(entry.value)")
.widgetLabel {
Text(entry.label)
}
default:
Text(entry.label)
}
}
}
WIDGET DEFINITION:
struct MyComplication: Widget {
let kind: String = "MyComplication"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: ComplicationProvider()) { entry in
ComplicationView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
.configurationDisplayName("My Complication")
.description("Shows current status on watch face")
.supportedFamilies([
.accessoryCircular,
.accessoryRectangular,
.accessoryInline,
.accessoryCorner
])
}
}
WIDGET BUNDLE:
@main
struct MyWidgetBundle: WidgetBundle {
var body: some Widget {
MyComplication()
}
}
CRITICAL RULES:
.containerBackground(.fill.tertiary, for: .widget) is REQUIRED.widgetAccentable() on elements that should tint with the watch face color.accessoryCircular for the most common single-value complicationShared/ directorystatic let for Swift 6 concurrencytesting
Use for 3D games: racing, 3D sports, board games, marble maze, tower defense, bowling. SceneKit + SceneView architecture, 3D scene hierarchy, physics, game loop, primitives, materials, cameras, particles, audio.
documentation
Game UI patterns: SwiftUI HUD overlays on SpriteKit, menus (main/pause/game-over), virtual joystick/d-pad, score displays, health bars, tutorial onboarding.
tools
Download free game sprites/textures/3D models and generate procedural assets. Covers nw_download_asset tool, texture factories, sprite atlas organization, 3D model loading, and programmatic asset creation.
testing
Use for 2D games: arcade, puzzle, sports, ping pong, platformer, shooter, 2D racing. SpriteKit + SpriteView architecture, scene hierarchy, physics, game loop, audio, particles, game feel.