Agent skill

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.

Stars 127
Forks 10

Install this agent skill to your Project

npx add-skill https://github.com/rshankras/claude-code-apple-skills/tree/main/skills/generators/tipkit-generator

SKILL.md

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

Expand your agent's capabilities with these related and highly-rated skills.

rshankras/claude-code-apple-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.

127 10
Explore
rshankras/claude-code-apple-skills

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.

127 10
Explore
rshankras/claude-code-apple-skills

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.

127 10
Explore
rshankras/claude-code-apple-skills

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.

127 10
Explore
rshankras/claude-code-apple-skills

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.

127 10
Explore
rshankras/claude-code-apple-skills

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.

127 10
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results