Agent skill
watchOS
watchOS development guidance including SwiftUI for Watch, Watch Connectivity, complications, and watch-specific UI patterns. Use for watchOS code review, best practices, or Watch app development.
Install this agent skill to your Project
npx add-skill https://github.com/rshankras/claude-code-apple-skills/tree/main/skills/watchos
SKILL.md
watchOS Development
Comprehensive guidance for watchOS app development with SwiftUI, Watch Connectivity, and complications.
When This Skill Activates
Use this skill when the user:
- Is building a watchOS app or Watch extension
- Asks about Watch Connectivity (iPhone ↔ Watch sync)
- Needs help with complications or ClockKit
- Wants to implement watch-specific UI patterns
- Asks about WidgetKit complications or migrating from ClockKit to WidgetKit
- Wants to build watch face complications (accessoryCircular, accessoryRectangular, accessoryCorner, accessoryInline)
- Asks about HealthKit on watchOS, workout sessions, heart rate, or fitness tracking
- Needs Extended Runtime sessions for background workout tracking
- Wants to build watchOS widgets or Smart Stack widgets
- Asks about widget relevance, Smart Stack ordering, or widget suggestions
- Needs to share widgets cross-platform between iOS and watchOS
Key Principles
1. Watch-First Design
- Glanceable content - users look for seconds, not minutes
- Quick interactions - 2 seconds or less
- Essential information only - no scrolling walls of text
- Large touch targets - minimum 38pt height
2. Independent vs Companion
- Prefer independent Watch apps when possible
- Use Watch Connectivity for data sync, not as dependency
- Cache data locally for offline access
- Handle connectivity failures gracefully
3. Performance
- Minimize background work (battery)
- Use complication updates sparingly
- Prefer timeline-based content over live updates
- Keep views lightweight
Architecture Patterns
App Structure
@main
struct MyWatchApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Navigation
// Use NavigationStack (watchOS 9+)
NavigationStack {
List {
NavigationLink("Item 1", value: Item.one)
NavigationLink("Item 2", value: Item.two)
}
.navigationDestination(for: Item.self) { item in
ItemDetailView(item: item)
}
}
// TabView for main sections
TabView {
HomeView()
ActivityView()
SettingsView()
}
.tabViewStyle(.verticalPage)
List Design
List {
ForEach(items) { item in
ItemRow(item: item)
}
.onDelete(perform: delete)
}
.listStyle(.carousel) // For focused content
.listStyle(.elliptical) // For browsing
Watch Connectivity
Session Setup
import WatchConnectivity
@Observable
final class WatchConnectivityManager: NSObject, WCSessionDelegate {
static let shared = WatchConnectivityManager()
private(set) var isReachable = false
override init() {
super.init()
if WCSession.isSupported() {
WCSession.default.delegate = self
WCSession.default.activate()
}
}
// Required delegate methods
func session(_ session: WCSession, activationDidCompleteWith state: WCSessionActivationState, error: Error?) {
isReachable = session.isReachable
}
#if os(iOS)
func sessionDidBecomeInactive(_ session: WCSession) {}
func sessionDidDeactivate(_ session: WCSession) {
WCSession.default.activate()
}
#endif
}
Data Transfer Methods
| Method | Use Case | Delivery |
|---|---|---|
updateApplicationContext |
Latest state (settings) | Overwrites previous |
sendMessage |
Real-time, both apps active | Immediate |
transferUserInfo |
Queued data | Guaranteed, in order |
transferFile |
Large data | Background transfer |
// Application Context (most common)
func updateContext(_ data: [String: Any]) throws {
try WCSession.default.updateApplicationContext(data)
}
// Real-time messaging
func sendMessage(_ message: [String: Any]) {
guard WCSession.default.isReachable else { return }
WCSession.default.sendMessage(message, replyHandler: nil)
}
// Receiving data
func session(_ session: WCSession, didReceiveApplicationContext context: [String: Any]) {
Task { @MainActor in
// Update UI with received data
}
}
Complications
Timeline Provider
import ClockKit
struct ComplicationController: CLKComplicationDataSource {
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
let descriptor = CLKComplicationDescriptor(
identifier: "myComplication",
displayName: "My App",
supportedFamilies: [.circularSmall, .modularSmall, .graphicCircular]
)
handler([descriptor])
}
func getCurrentTimelineEntry(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void
) {
let template = makeTemplate(for: complication.family)
let entry = CLKComplicationTimelineEntry(date: .now, complicationTemplate: template)
handler(entry)
}
}
WidgetKit Complications (watchOS 9+)
import WidgetKit
import SwiftUI
struct MyComplication: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(
kind: "MyComplication",
provider: ComplicationProvider()
) { entry in
ComplicationView(entry: entry)
}
.configurationDisplayName("My Complication")
.supportedFamilies([
.accessoryCircular,
.accessoryRectangular,
.accessoryCorner,
.accessoryInline
])
}
}
UI Components
Digital Crown
@State private var crownValue = 0.0
ScrollView {
// Content
}
.focusable()
.digitalCrownRotation($crownValue)
Haptic Feedback
WKInterfaceDevice.current().play(.click)
WKInterfaceDevice.current().play(.success)
WKInterfaceDevice.current().play(.failure)
Now Playing
import WatchKit
NowPlayingView() // Built-in now playing controls
Workout Apps
import HealthKit
@Observable
class WorkoutManager {
let healthStore = HKHealthStore()
var session: HKWorkoutSession?
var builder: HKLiveWorkoutBuilder?
func startWorkout(type: HKWorkoutActivityType) async throws {
let config = HKWorkoutConfiguration()
config.activityType = type
config.locationType = .outdoor
session = try HKWorkoutSession(healthStore: healthStore, configuration: config)
builder = session?.associatedWorkoutBuilder()
session?.startActivity(with: .now)
try await builder?.beginCollection(at: .now)
}
}
Best Practices
Performance
- Use
@ObservableoverObservableObject(watchOS 10+) - Limit background refreshes
- Cache images locally
- Use lazy loading for lists
Battery
- Minimize location updates
- Use scheduled background tasks
- Prefer complications over frequent refreshes
- Batch network requests
User Experience
- Always show loading states
- Provide haptic feedback
- Support keyboard input
- Use clear iconography
Testing
Simulator
- Test with different watch sizes
- Verify complications in all families
- Test Watch Connectivity with paired iPhone simulator
On Device
- Test battery impact
- Verify haptics feel appropriate
- Test in different lighting conditions
Decision Tree
Choose the right reference file based on what the user needs:
What are you building?
|
+- iPhone <-> Watch data sync
| -> watch-connectivity.md
| +- Session management, application context, real-time messaging
| +- File transfers, offline caching, complication push updates
|
+- Watch face complications
| -> complications.md
| +- ClockKit (legacy) vs WidgetKit (modern) complications
| +- Migration from ClockKit to WidgetKit
| +- Complication families (circular, rectangular, corner, inline)
| +- Timeline providers, reload strategies, gauges
|
+- Health / fitness / workout tracking
| -> health-fitness.md
| +- HealthKit authorization and data types
| +- HKWorkoutSession and HKLiveWorkoutBuilder
| +- Real-time heart rate, calories, distance
| +- Extended Runtime sessions, route tracking
|
+- watchOS widgets / Smart Stack
| -> widgets-for-watch.md
| +- Smart Stack configuration and relevance
| +- Cross-platform widget sharing (iOS + watchOS)
| +- watchOS-specific design (dark background, small screen)
|
+- General watchOS app development
-> This file (SKILL.md)
+- App structure, navigation, lists
+- Digital Crown, haptics, Now Playing
Reference Files
| File | Content |
|---|---|
| watch-connectivity.md | iPhone <-> Watch sync, session management, data transfer, offline caching |
| complications.md | ClockKit to WidgetKit migration, complication families, timeline providers, gauges |
| health-fitness.md | HealthKit, workout sessions, heart rate, Extended Runtime, route tracking, privacy |
| widgets-for-watch.md | Smart Stack widgets, relevance, cross-platform sharing, watchOS design |
External References
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
legal
Legal document generation and compliance guidance for indie Apple developers. Covers privacy policies, terms of service, EULAs, GDPR/CCPA/DPDP compliance, and Apple App Store legal requirements. Use when user needs legal documents or compliance guidance.
privacy-policy
Generate privacy policies, terms of service, and EULAs for Apple platform apps. Detects data collection patterns, third-party SDKs, and generates region-specific legal documents with Apple Privacy Nutrition Label mapping. Use when user needs legal documents or data collection disclosure for App Store submission.
ios-development
Comprehensive iOS development guidance including Swift best practices, SwiftUI patterns, UI/UX review against HIG, and app planning. Use for iOS code review, best practices, accessibility audits, or planning new iOS apps.
assistive-access
Assistive Access implementation for cognitive accessibility including simplified scenes, navigation icons, runtime detection, and design principles. Use when optimizing apps for Assistive Access mode.
ui-review
Review SwiftUI code for iOS/watchOS Human Interface Guidelines compliance, font usage, Dynamic Type support, and accessibility. Use when user mentions UI review, HIG, accessibility audit, font checks, or wants to verify interface design against Apple standards.
navigation-patterns
SwiftUI navigation architecture patterns including NavigationStack, NavigationSplitView, TabView, programmatic navigation, and custom transitions. Use when reviewing or building navigation, fixing navigation bugs, or architecting app flow.
Didn't find tool you were looking for?