swiftship/internal/skills/data/always-watchos/watchos-patterns/SKILL.md
watchOS platform patterns: Digital Crown, Always On Display, battery constraints, WKApplicationDelegate lifecycle, wrist detection. Use when working on shared watchOS patterns related to watchos patterns.
npx skillsauth add abdullah4ai/apple-dev-docs watchos-patternsInstall 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.
The Digital Crown is the primary input for value adjustment on Apple Watch.
// Basic rotation binding
@State private var crownValue: Double = 0
ScrollView {
content
}
.digitalCrownRotation($crownValue)
// Bounded rotation with haptics
@State private var volume: Double = 50
VolumeView(level: volume)
.digitalCrownRotation(
$volume,
from: 0,
through: 100,
by: 1,
sensitivity: .medium,
isContinuous: false,
isHapticFeedbackEnabled: true
)
.low — large physical rotation per unit (precise adjustment).medium — balanced (default for most use cases).high — small physical rotation per unit (fast scrolling)Only the focused view receives Crown events:
@FocusState private var crownFocused: Bool
VStack {
MetricView(value: crownValue)
}
.digitalCrownRotation($crownValue)
.focusable()
.focused($crownFocused)
.onAppear { crownFocused = true }
watchOS apps should support Always On Display when the wrist is lowered.
@Environment(\.isLuminanceReduced) var isLuminanceReduced
var body: some View {
VStack {
if isLuminanceReduced {
// Simplified, dim view — reduce updates and brightness
Text(Date.now, style: .time)
.font(AppTheme.Fonts.title)
} else {
// Full interactive view
DetailedContentView()
}
}
}
\.isLuminanceReduced to detect Always On stateTimelineView(.everyMinute) for clock-like updates in reduced modeisLuminanceReduced == trueTimelineView(.everyMinute) { context in
if isLuminanceReduced {
Text(context.date, style: .time)
} else {
LiveActivityView()
}
}
Apple Watch has very limited battery — every CPU/GPU cycle matters.
.animation only for state transitions)WKApplicationRefreshBackgroundTaskTimelineView over Timer for periodic updates.task for async work — it cancels automatically when the view disappearsfunc handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
for task in backgroundTasks {
switch task {
case let refreshTask as WKApplicationRefreshBackgroundTask:
// Update data
scheduleNextRefresh()
refreshTask.setTaskCompletedWithSnapshot(true)
default:
task.setTaskCompletedWithSnapshot(false)
}
}
}
import WatchKit
class AppDelegate: NSObject, WKApplicationDelegate {
func applicationDidFinishLaunching() {
// App launched
}
func applicationDidBecomeActive() {
// App is active and visible
}
func applicationWillResignActive() {
// App is about to go inactive
}
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
// Handle background tasks
}
}
@main
struct MyWatchApp: App {
@WKApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
@Environment(\.scenePhase) var scenePhase
.onChange(of: scenePhase) { _, phase in
switch phase {
case .active:
refreshData()
case .inactive:
saveState()
case .background:
scheduleBackgroundRefresh()
@unknown default:
break
}
}
For workouts or navigation that need to keep running:
import WatchKit
let session = WKExtendedRuntimeSession()
session.start()
// Session keeps app alive for the allowed duration
session.invalidate() // when done
// Watch is authenticated when on wrist and unlocked
// For sensitive features, confirm with LAContext
import LocalAuthentication
func requireAuth() async -> Bool {
let context = LAContext()
guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: nil) else {
return false
}
do {
return try await context.evaluatePolicy(
.deviceOwnerAuthentication,
localizedReason: "Access sensitive data"
)
} catch {
return false
}
}
isLuminanceReduced for Always On DisplayWKApplicationDelegate for lifecycle hooks and background taskstools
Apple platform skill for docs, WWDC lookup, App Store Connect work, and SwiftUI app generation. Use repo-local `node cli.js` for Apple docs and WWDC search, `appledev store` for App Store Connect workflows, and `appledev build` for app scaffolding or fix loops on macOS. USE WHEN: Apple APIs, WWDC sessions, TestFlight/App Store tasks, or building/fixing Apple-platform apps. DON'T USE WHEN: non-Apple platforms, generic backend work, or general web research. EDGE CASES: docs-only queries use `node cli.js` in this repo, not `appledev`; release workflows use `appledev store`; app scaffolding uses `appledev build`; rules-only requests can read `references/ios-rules/` or `references/swiftui-guides/` progressively without invoking binaries.
tools
All-in-one Apple developer skill with three integrated tools shipped as a single unified binary. (1) Documentation search across Apple frameworks, symbols, and 1,267 WWDC sessions from 2014-2025. No credentials needed. (2) App Store Connect CLI with 120+ commands covering builds (find/wait/upload), TestFlight, pre-submission validate, submissions, signing, subscriptions (family-sharable), IAP, analytics, Xcode Cloud, metadata workflows, release pipeline dashboard, insights, win-back offers, promoted purchases, product pages, nominations, accessibility declarations, pre-orders, pricing filters, localizations update, diff, webhooks with local receiver, workflow automation, and more. Requires App Store Connect API key. (3) Multi-platform app builder (iOS/watchOS/tvOS/iPad/macOS/visionOS) that generates complete Swift/SwiftUI apps from natural language with auto-fix, simulator launch, interactive chat mode, and open-in-Xcode. Requires an LLM API key and Xcode. Includes 38 iOS development rules and 12 SwiftUI best practice guides for Liquid Glass, navigation, state management, and modern APIs. All three tools ship as one binary (appledev). USE WHEN: Apple API docs, App Store Connect management, WWDC lookup, or building iOS/watchOS/tvOS/macOS/visionOS apps from scratch. DON'T USE WHEN: non-Apple platforms or general coding.
testing
watchOS complications: WidgetKit complication families, accessory sizes, timeline providers for watch face. Use when implementing watchOS-specific patterns related to widgets.
development
watchOS haptic feedback: WKInterfaceDevice preset haptic types for wrist-based feedback. Use when implementing watchOS-specific patterns related to haptics.