tipkit-generator

Generate TipKit infrastructure with inline/popover tips, rules, display frequency, and testing utilities. Use when adding contextual tips or feature discovery to an iOS/macOS app.

149 stars

Best use case

tipkit-generator is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Generate TipKit infrastructure with inline/popover tips, rules, display frequency, and testing utilities. Use when adding contextual tips or feature discovery to an iOS/macOS app.

Teams using tipkit-generator should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/tipkit-generator/SKILL.md --create-dirs "https://raw.githubusercontent.com/rshankras/claude-code-apple-skills/main/skills/generators/tipkit-generator/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/tipkit-generator/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How tipkit-generator Compares

Feature / Agenttipkit-generatorStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Generate TipKit infrastructure with inline/popover tips, rules, display frequency, and testing utilities. Use when adding contextual tips or feature discovery to an iOS/macOS app.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# TipKit Generator

Generate a complete TipKit setup for contextual tips and feature discovery, including tip definitions, rules, display frequency, inline and popover presentation, and testing utilities.

## When This Skill Activates

Use this skill when the user:
- Asks to "add tips" or "add TipKit"
- Mentions "contextual tips" or "feature discovery"
- Wants "popover tips" or "inline tips"
- Asks about "coach marks" or "user education"
- Mentions "onboarding hints" or "tip prompts"
- Wants to "highlight new features" or "guide users"

## Pre-Generation Checks

### 1. Project Context Detection
- [ ] Check deployment target (TipKit requires iOS 17+ / macOS 14+)
- [ ] Identify if SwiftUI or UIKit project
- [ ] Find App entry point location for Tips.configure()
- [ ] Check for existing TipKit implementations

### 2. Conflict Detection
Search for existing TipKit usage:
```
Glob: **/*Tip*.swift
Grep: "import TipKit" or "Tips.configure"
```

If found, ask user:
- Extend existing tip infrastructure?
- Replace existing tips?

## Configuration Questions

Ask user via AskUserQuestion:

1. **What features need tips?**
   - List the features or UI elements that should have tips
   - Example: "search bar, filter button, swipe-to-delete gesture"

2. **Tip presentation style?** (per tip or general preference)
   - Inline (TipView embedded in layout)
   - Popover (attached to a control)
   - Both

3. **Rule types needed?**
   - Parameter-based (show after user meets condition, e.g., has viewed a screen 3 times)
   - Event-based (show after user performs an action N times)
   - Both

4. **Display frequency?**
   - Immediate (tips show as soon as eligible)
   - Hourly
   - Daily
   - Weekly
   - Monthly

5. **Tip ordering?**
   - Independent (tips show whenever eligible)
   - Ordered (use TipGroup to show tips in sequence)

## Generation Process

### Step 1: Read Templates

Read the templates file for code patterns:
```
Read("skills/generators/tipkit-generator/templates.md")
```

### Step 2: Create Core Files

Generate these files based on configuration:
1. `Tips/` directory with one file per tip (e.g., `SearchTip.swift`, `FilterTip.swift`)
2. `Tips/TipEvents.swift` - Centralized event definitions
3. `Tips/TipsConfiguration.swift` - Tips.configure() setup and testing utilities

### Step 3: Determine File Location

Check project structure:
- If `Sources/` exists -> `Sources/Tips/`
- If `App/` exists -> `App/Tips/`
- Otherwise -> `Tips/`

### Step 4: Integrate Tips

- Add `Tips.configure()` call in App entry point
- Add `TipView` or `.popoverTip()` at the appropriate view locations
- Wire up event donation at action sites
- Wire up tip invalidation where appropriate

## Output Format

After generation, provide:

### Files Created
```
Sources/Tips/
├── SearchTip.swift            # Tip with rules and options
├── FilterTip.swift            # Another tip definition
├── TipEvents.swift            # Centralized event definitions
└── TipsConfiguration.swift    # Tips.configure() + testing helpers
```

### Integration Steps

**App Entry Point (Required):**
```swift
import TipKit

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .task {
                    try? Tips.configure([
                        .displayFrequency(.daily),
                        .datastoreLocation(.applicationDefault)
                    ])
                }
        }
    }
}
```

**Inline Tip:**
```swift
import TipKit

struct SearchView: View {
    let searchTip = SearchTip()

    var body: some View {
        VStack {
            TipView(searchTip)
            SearchBar()
        }
    }
}
```

**Popover Tip:**
```swift
import TipKit

struct ToolbarView: View {
    let filterTip = FilterTip()

    var body: some View {
        Button("Filter", systemImage: "line.3.horizontal.decrease.circle") {
            // action
        }
        .popoverTip(filterTip)
    }
}
```

**Event Donation (at action site):**
```swift
Button("Search") {
    performSearch()
    SearchTip.searchPerformed.donate()
}
```

**Tip Invalidation (when tip is no longer relevant):**
```swift
func onFeatureUsed() {
    // User discovered the feature, invalidate the tip
    searchTip.invalidate(reason: .actionPerformed)
}
```

### Testing Instructions

1. **Reset DataStore between runs:**
   ```swift
   // Add to a debug menu or call in preview
   try? Tips.resetDatastore()
   ```

2. **Show all tips for testing:**
   ```swift
   // Ignores rules and frequency -- shows everything
   Tips.showAllTipsForTesting()
   ```

3. **Show specific tips for testing:**
   ```swift
   Tips.showTipsForTesting([SearchTip.self])
   ```

4. **Test scenarios:**
   - Launch app fresh -- eligible tips should appear per display frequency
   - Perform actions that donate events -- event-based tips should appear when thresholds met
   - Tap tip close button -- tip should not reappear
   - Invalidate tip programmatically -- tip should dismiss and not reappear

## Common Gotchas

1. **Forgetting Tips.configure()** -- Tips will never appear if you do not call `Tips.configure()` before any tip is displayed. This must happen early, typically in the App `body` or `.task`.

2. **Rules not evaluating** -- Parameter-based rules require you to set the parameter value explicitly. If you define `@Parameter static var hasSeenFeature = false` but never set it to `true`, the rule never passes.

3. **DataStore conflicts in tests** -- If you run unit tests and the app simultaneously, they may share the same DataStore. Use `.datastoreLocation(.url(...))` to isolate them.

4. **Display frequency blocking tips** -- If you set `.displayFrequency(.daily)` and a tip was already shown today, no new tips will appear until tomorrow. Use `.immediate` during development.

5. **Tips not dismissing after invalidation** -- You must hold a reference to the tip instance and call `.invalidate(reason:)` on that instance. Creating a new instance and invalidating it does nothing to the displayed tip.

6. **TipGroup ordering ignored** -- Tips in a TipGroup only show in order if their rules are all satisfied. If Tip B's rules pass but Tip A's do not, neither will show (Tip A blocks Tip B).

## Patterns

### Good Patterns

- One tip struct per file for clarity
- Centralize event definitions in a single file
- Use `.actionPerformed` invalidation reason when the user completes the action the tip describes
- Use `TipGroup` when tips should appear in a logical sequence
- Provide a debug/testing menu that calls `Tips.resetDatastore()`
- Use meaningful tip IDs that describe the feature

### Bad Patterns

- Defining all tips in a single massive file
- Forgetting to call `Tips.configure()` in the App entry point
- Using `.immediate` display frequency in production (overwhelming users)
- Hardcoding tip text instead of using localized strings for shipped apps
- Creating a new tip instance to invalidate instead of using the displayed instance
- Placing `TipView` inside a `ScrollView` without considering layout impact

## References

- **templates.md** - Code templates for tips, rules, configuration, and TipGroup

Related Skills

characterization-test-generator

149
from rshankras/claude-code-apple-skills

Generates tests that capture current behavior of existing code before refactoring. Use when you need a safety net before AI-assisted refactoring or modifying legacy code.

prd-generator

149
from rshankras/claude-code-apple-skills

Generates comprehensive Product Requirements Document from product plan. Creates PRD.md with features, user stories, acceptance criteria, and success metrics. Use when creating product requirements.

idea-generator

149
from rshankras/claude-code-apple-skills

Brainstorm and rank iOS/macOS app ideas tailored to developer skills. Use when user says "what should I build", "give me app ideas", "I don't know what to build", "brainstorm app ideas", or "help me find an app idea".

widget-generator

149
from rshankras/claude-code-apple-skills

Generate WidgetKit widgets for iOS/macOS home screen and lock screen with timeline providers, interactive elements, and App Intent configuration. Use when adding widgets to an app.

test-generator

149
from rshankras/claude-code-apple-skills

Generate test templates for unit tests, integration tests, and UI tests using Swift Testing and XCTest. Use when adding tests to iOS/macOS apps.

paywall-generator

149
from rshankras/claude-code-apple-skills

Generates StoreKit 2 subscription paywall with modern SwiftUI views. Use when user wants to add subscriptions, paywall, or in-app purchases.

onboarding-generator

149
from rshankras/claude-code-apple-skills

Generates multi-step onboarding flows with persistence for iOS/macOS apps. Use when user wants to add onboarding, welcome screens, or first-launch experience.

live-activity-generator

149
from rshankras/claude-code-apple-skills

Generate ActivityKit Live Activity infrastructure with Dynamic Island layouts, Lock Screen presentation, and push-to-update support. Use when adding Live Activities to an iOS app.

app-icon-generator

149
from rshankras/claude-code-apple-skills

Generates app icons programmatically using CoreGraphics following Apple HIG. Use when user wants to create, generate, or design an app icon for macOS or iOS.

accessibility-generator

149
from rshankras/claude-code-apple-skills

Generate accessibility infrastructure for VoiceOver, Dynamic Type, and accessibility features. Use when improving app accessibility, adding accessibility labels and hints, or auditing compliance.

generators

149
from rshankras/claude-code-apple-skills

Code generator skills that produce production-ready Swift code for common app components. Use when user wants to add logging, analytics, onboarding, review prompts, networking, authentication, paywalls, settings, persistence, error monitoring, CI/CD pipelines, localization, push notifications, deep linking, testing, accessibility, widgets, feature flags, app icons, image caching, pagination, HTTP caching, share cards, social export, subscription lifecycle, referral systems, watermarks, streak tracking, milestone celebrations, what's new screens, lapsed user re-engagement, usage insights, variable rewards, consent flows, account deletion, permission priming, force updates, state restoration, debug menus, offline queues, feedback forms, announcement banners, quick win sessions, Spotlight indexing, App Clips, screenshot automation, background processing, app extensions, or data export.

watchOS

149
from rshankras/claude-code-apple-skills

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.