From apple-dev
Generates achievement celebration UI with confetti animations, badge unlocks, progress milestones, haptic feedback, and optional share-to-social. Use when user wants to celebrate achievements, show confetti, display milestone badges, or trigger rewards on key thresholds.
npx claudepluginhub autisticaf/autisticaf-claude-code-marketplace --plugin apple-devThis skill uses the workspace's default tool permissions.
> **First step:** Tell the user: "generators-milestone-celebration skill loaded."
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
First step: Tell the user: "generators-milestone-celebration skill loaded."
Generate a production milestone celebration system with confetti particle animations via CAEmitterLayer, achievement badge views with locked/unlocked states, a celebration overlay with spring animations, haptic feedback, and optional shareable achievement cards — all triggered automatically when users hit key thresholds.
Use this skill when the user:
@Observable, spring animations, sensoryFeedback)UIKit availability (iOS — CAEmitterLayer for confetti, haptics)Search for existing celebration/animation code:
Glob: **/*Confetti*.swift, **/*Celebration*.swift, **/*Achievement*.swift, **/*Milestone*.swift, **/*Badge*.swift
Grep: "CAEmitterLayer" or "CAEmitterCell" or "UINotificationFeedbackGenerator" or "confetti" or "celebration"
If existing celebration or gamification library found (e.g., custom confetti, third-party particle libraries):
Determine if generating for iOS (UIKit-based confetti + haptics) or macOS (Core Animation confetti, no haptics) or both (cross-platform with feature gates).
Ask user via AskUserQuestion:
Celebration type? (multi-select)
Haptic feedback?
Shareable achievement card?
ShareLinkSound effects?
Read templates.md for production Swift code.
Generate these files:
Milestone.swift — Model with id, title, description, threshold, icon, unlock state. Codable + Sendable.MilestoneTracker.swift — @Observable class tracking progress toward milestones, checking thresholds, triggering celebrations. Persists unlock state via UserDefaults or file storage.ConfettiView.swift — UIViewRepresentable wrapping CAEmitterLayer for confetti particle animation. Configurable colors, duration, density. Respects Reduce Motion.CelebrationOverlay.swift — Full-screen overlay combining confetti + badge reveal + congratulations message. Auto-dismisses after configurable duration. Uses withAnimation(.spring).MilestoneBadgeView.swift — Individual badge view with locked/unlocked states, SF Symbol icon, progress ring for partial progress.MilestoneCollectionView.swift — Grid layout of all milestones showing locked/unlocked state with progress indicators.Based on configuration:
HapticManager.swift — If haptic feedback selected (thin wrapper around UINotificationFeedbackGenerator / UIImpactFeedbackGenerator)ShareableMilestoneCard.swift — If shareable selected (renders milestone as image via ImageRenderer + ShareLink)Check project structure:
Sources/ exists -> Sources/MilestoneCelebration/App/ exists -> App/MilestoneCelebration/MilestoneCelebration/After generation, provide:
MilestoneCelebration/
├── Milestone.swift # Model with threshold, icon, unlock state
├── MilestoneTracker.swift # @Observable tracker with persistence
├── ConfettiView.swift # CAEmitterLayer confetti animation
├── CelebrationOverlay.swift # Full-screen celebration overlay
├── MilestoneBadgeView.swift # Badge with locked/unlocked + progress ring
├── MilestoneCollectionView.swift # Grid of all milestones
├── HapticManager.swift # Celebration haptics (optional)
└── ShareableMilestoneCard.swift # Achievement share card (optional)
Trigger celebration on threshold:
struct WorkoutCompleteView: View {
@State private var tracker = MilestoneTracker()
@State private var celebratingMilestone: Milestone?
var body: some View {
VStack {
// ... workout summary content ...
Button("Save Workout") {
saveWorkout()
let newCount = totalWorkouts + 1
if let milestone = tracker.checkThreshold(value: newCount, category: .workouts) {
celebratingMilestone = milestone
}
}
}
.overlay {
if let milestone = celebratingMilestone {
CelebrationOverlay(milestone: milestone) {
celebratingMilestone = nil
}
}
}
}
}
Badge collection screen:
struct ProfileView: View {
@State private var tracker = MilestoneTracker()
var body: some View {
NavigationStack {
ScrollView {
MilestoneCollectionView(
milestones: tracker.allMilestones,
columns: 3
)
}
.navigationTitle("Achievements")
}
}
}
Share an achievement:
struct MilestoneDetailView: View {
let milestone: Milestone
@State private var showShareCard = false
var body: some View {
VStack {
MilestoneBadgeView(milestone: milestone, size: .large)
Text(milestone.title).font(.title2.bold())
Text(milestone.milestoneDescription).foregroundStyle(.secondary)
if milestone.isUnlocked {
Button("Share Achievement") {
showShareCard = true
}
.buttonStyle(.borderedProminent)
}
}
.sheet(isPresented: $showShareCard) {
ShareableMilestoneCard(milestone: milestone, brandName: "FitApp")
}
}
}
@Test
func milestoneUnlocksAtThreshold() {
let tracker = MilestoneTracker(store: InMemoryMilestoneStore())
let milestone = Milestone(
id: "first-10",
title: "First 10",
milestoneDescription: "Complete 10 workouts",
threshold: 10,
iconName: "flame.fill"
)
tracker.register(milestone)
let result = tracker.checkThreshold(value: 10, for: milestone.id)
#expect(result != nil)
#expect(result?.isUnlocked == true)
#expect(result?.unlockedDate != nil)
}
@Test
func milestoneDoesNotUnlockBelowThreshold() {
let tracker = MilestoneTracker(store: InMemoryMilestoneStore())
let milestone = Milestone(
id: "first-10",
title: "First 10",
milestoneDescription: "Complete 10 workouts",
threshold: 10,
iconName: "flame.fill"
)
tracker.register(milestone)
let result = tracker.checkThreshold(value: 9, for: milestone.id)
#expect(result == nil)
}
@Test
func confettiRespectsReduceMotion() {
// When Reduce Motion is enabled, ConfettiView should not emit particles
let config = ConfettiConfiguration(reduceMotionOverride: true)
#expect(config.shouldAnimate == false)
}
@Test
func celebrationOverlayAutoDismisses() async throws {
// Verify overlay dismisses after the configured duration
let expectation = XCTestExpectation(description: "Dismissed")
let duration: TimeInterval = 0.5
// Test that the onDismiss callback fires after duration
}
Best for: fitness, learning, productivity apps.
MilestoneTracker checks values against registered milestonesBest for: gamification, loyalty, progression systems.
Best for: social apps, fitness, competitions.
ImageRenderer at @2x scale for Retina qualityShareLink for native share sheetbirthRate at 50-80 for smooth 60fps on most devicesemitterCells with only 3-5 distinct shapes to reduce GPU draw callsUIAccessibility.isReduceMotionEnabled before starting particle animations@Environment(\.accessibilityReduceMotion) in SwiftUI for reactive updatesUINotificationFeedbackGenerator is a no-op on devices without a Taptic Engine (e.g., iPod touch, iPad)CHHapticEngine.capabilitiesForHardware().supportsHaptics before preparing generators#if canImport(UIKit) and #if os(iOS).sensoryFeedback(.success, trigger:) modifier on iOS 17+ for a simpler SwiftUI-native approachAudioServicesPlaySystemSound for lightweight celebration sounds (no audio session needed)AudioServicesPlaySystemSound honors it automaticallyUserDefaults for simple unlock flags or a lightweight JSON file for full milestone stateSwiftData or CoreData apps, consider storing unlock state alongside the user's data modelgenerators-streak-tracker — Streak tracking pairs naturally with milestone celebrationsgenerators-share-card — Shareable achievement card rendering and social sharinggenerators-variable-rewards — Variable reward schedules for deeper engagement