Communitygithub.com

JordanCoin/ios-skills-collection

Implémenter, réviser ou améliorer les pourboires et l'intégration dans l'application à l'aide du framework TipKit d'Apple. Utilisez-le pour ajouter des info-bulles de découverte de fonctionnalités, des flux d'intégration, des conseils contextuels, des expériences de première utilisation, des marques de coach ou pour travailler avec le protocole Tip, TipView, popoverTip, les règles de conseil, les événements de conseil ou l'interface utilisateur de formation aux fonctionnalités.

Qu'est-ce que ios-skills-collection ?

TipKit est un framework Apple pour iOS 17+ qui simplifie l'ajout de conseils de découverte de fonctionnalités, d'indices contextuels et de marques de coach d'intégration dans les applications SwiftUI. Il gère automatiquement la fréquence d'affichage, les règles d'éligibilité et la persistance, garantissant que les conseils apparaissent au bon moment et disparaissent une fois que l'utilisateur a appris la fonctionnalité. La formation couvre la configuration (`Tips.configure()` dans `App.init`), la définition de conseils avec le protocole Tip, l'affichage avec TipView et .popoverTip(), et le contrôle de l'éligibilité via des règles basées sur des paramètres et des événements. Elle explique également comment utiliser TipGroup pour séquencer les conseils, ajouter des actions aux conseils, et fournit des utilitaires de test pour le développement. Ce contenu est tiré de la compétence **JordanCoin/ios-skills-collection** et aide les développeurs à implémenter des expériences d'intégration et de découverte de fonctionnalités de manière fiable et cohérente.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/JordanCoin/ios-skills-collection/tree/HEAD/skills/dpearson2699--tipkit

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

TipKit

Ajoutez des conseils de découverte de fonctionnalités, des indices contextuels et des marques de coach d'intégration aux applications iOS 17+ à l'aide du framework TipKit d'Apple. TipKit gère la fréquence d'affichage, les règles d'éligibilité et la persistance afin que les conseils apparaissent au bon moment et disparaissent une fois que l'utilisateur a appris la fonctionnalité.

Contenu

Configuration

Appelez Tips.configure() une fois dans App.init, avant que les vues ne soient rendues. Cette action initialise le magasin de données des conseils et commence l'évaluation des règles. L'appeler plus tard risque une situation de compétition où les vues de conseils tentent de s'afficher avant que le magasin de données ne soit prêt.

import SwiftUI
import TipKit

@main
struct MyApp: App {
    init() {
        try? Tips.configure([
            .datastoreLocation(.applicationDefault)
        ])
    }

    var body: some Scene {
        WindowGroup { ContentView() }
    }
}

Options DatastoreLocation

OptionCas d'utilisation
.applicationDefaultEmplacement par défaut, bac à sable de l'application (la plupart des applications)
.groupContainer(identifier:)Partager l'état des conseils entre l'application et les extensions
.url(_:)URL de fichier personnalisée pour un contrôle total de l'emplacement de stockage

Synchronisation CloudKit

Synchronisez l'état des conseils entre les appareils d'un utilisateur afin qu'il ne voie pas le même conseil sur chaque appareil. Ajoutez l'option de conteneur CloudKit en plus de l'emplacement du magasin de données.

try? Tips.configure([
    .datastoreLocation(.applicationDefault),
    .cloudKitContainer(.named("iCloud.com.example.app"))
])

Définition des conseils

Conformez une structure au protocole Tip. Fournissez au minimum un title. Ajoutez un message pour les détails d'accompagnement et une image pour une icône principale. Gardez les titres courts et orientés vers l'action car le conseil apparaît sous forme de légende compacte.

import TipKit

struct FavoriteTip: Tip {
    var title: Text { Text("Épinglez vos favoris") }
    var message: Text? { Text("Appuyez sur l'icône en forme de cœur pour enregistrer les éléments et y accéder rapidement.") }
    var image: Image? { Image(systemName: "heart") }
}

Propriétés : title (obligatoire), message (détail optionnel), image (icône principale optionnelle), actions (boutons optionnels), rules (conditions d'éligibilité optionnelles), options (fréquence d'affichage, nombre maximum).

Cycle de vie : En attente (règles non satisfaites) -> Éligible (toutes les règles passent) -> Invalidé (rejeté, actionné ou supprimé par programme). Une fois invalidé, un conseil ne réapparaît pas à moins que le magasin de données ne soit réinitialisé.

Affichage des conseils

Conseils intégrés avec TipView

Intégrez une TipView directement dans votre mise en page. Elle s'affiche sous forme de carte arrondie qui apparaît et disparaît avec une animation. Utilisez-la pour les conseils dans le contenu défilant.

let favoriteTip = FavoriteTip()
var body: some View {
    VStack {
        TipView(favoriteTip)
        ItemListView()
    }
}

Conseils contextuels avec .popoverTip()

Attachez un conseil comme une popover ancrée à n'importe quelle vue. Le framework dessine une flèche de la popover vers l'ancre. Utilisez-la pour les conseils pointant vers un contrôle spécifique.

Button { toggleFavorite() } label: { Image(systemName: "heart") }
    .popoverTip(favoriteTip)

// Contrôler la direction de la flèche (omettre pour laisser le système choisir)
.popoverTip(favoriteTip, arrowEdge: .bottom)

Style TipView personnalisé

Créez un style personnalisé pour contrôler l'apparence des conseils dans l'application. Conformez-vous à TipViewStyle et implémentez makeBody(configuration:).

struct CustomTipStyle: TipViewStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack(spacing: 12) {
            configuration.image?
                .font(.title2)
                .foregroundStyle(.tint)

            VStack(alignment: .leading, spacing: 4) {
                configuration.title
                    .font(.headline)
                configuration.message?
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
            }
        }
        .padding()
    }
}

// Appliquer globalement ou par vue
TipView(favoriteTip)
    .tipViewStyle(CustomTipStyle())

Règles des conseils

Les règles contrôlent quand un conseil devient éligible. Toutes les règles du tableau rules doivent passer avant que le conseil ne s'affiche. TipKit prend en charge deux types de règles : basées sur les paramètres et basées sur les événements.

Règles basées sur les paramètres

Utilisez @Parameter pour suivre l'état de l'application. Le conseil devient éligible lorsque la valeur du paramètre satisfait la condition de la règle.

struct FavoriteTip: Tip {
    @Parameter
    static var hasSeenList: Bool = false

    var title: Text { Text("Épinglez vos favoris") }

    var rules: [Rule] {
        #Rule(Self.$hasSeenList) { $0 == true }
    }
}

// Définir le paramètre lorsque l'utilisateur atteint la liste
FavoriteTip.hasSeenList = true

Règles basées sur les événements

Utilisez Tips.Event pour suivre les actions de l'utilisateur. Faites un don à l'événement à chaque fois que l'action se produit. La règle se déclenche lorsque le nombre de dons ou la condition de synchronisation est satisfaite. C'est idéal pour les conseils qui doivent apparaître après que l'utilisateur a effectué une action plusieurs fois sans découvrir une fonctionnalité connexe.

struct ShortcutTip: Tip {
    static let appOpenedEvent = Tips.Event(id: "appOpened")

    var title: Text { Text("Essayez l'action rapide") }

    var rules: [Rule] {
        #Rule(Self.appOpenedEvent) { $0.donations.count >= 3 }
    }
}

// Faites un don à chaque ouverture de l'application
ShortcutTip.appOpenedEvent.donate()

Combinaison de plusieurs règles

Placez plusieurs règles dans le tableau. Toutes doivent passer (ET logique).

struct AdvancedTip: Tip {
    @Parameter
    static var isLoggedIn: Bool = false

    static let featureUsedEvent = Tips.Event(id: "featureUsed")

    var title: Text { Text("Débloquez le mode avancé") }

    var rules: [Rule] {
        #Rule(Self.$isLoggedIn) { $0 == true }
        #Rule(Self.featureUsedEvent) { $0.donations.count >= 5 }
    }
}

Options de fréquence d'affichage

Contrôlez la fréquence d'apparition des conseils à l'aide de la propriété options.

struct DailyTip: Tip {
    var title: Text { Text("Rappel quotidien") }

    var options: [TipOption] {
        MaxDisplayCount(3)                   // Afficher au maximum 3 fois au total
        IgnoresDisplayFrequency(true)        // Ignorer la limite de fréquence globale
    }
}

La fréquence d'affichage globale est définie au moment de la configuration :

try? Tips.configure([
    .displayFrequency(.daily)  // .immediate, .hourly, .daily, .weekly, .monthly
])

Avec .daily, le système affiche au maximum un conseil par jour dans l'ensemble de l'application, sauf si un conseil spécifique définit IgnoresDisplayFrequency(true).

Actions des conseils

Ajoutez des boutons d'action à un conseil pour une interaction directe. Chaque action a un id et un label. Gérez l'action dans le gestionnaire d'actions de la vue du conseil.

struct FeatureTip: Tip {
    var title: Text { Text("Essayez le nouvel éditeur") }
    var message: Text? { Text("Nous avons ajouté un nouveau mode d'édition puissant.") }

    var actions: [Action] {
        Action(id: "open-editor", title: "Ouvrir l'éditeur")
        Action(id: "learn-more", title: "En savoir plus")
    }
}

Gérez les actions dans la vue :

TipView(featureTip) { action in
    switch action.id {
    case "open-editor":
        navigateToEditor()
        featureTip.invalidate(reason: .actionPerformed)
    case "learn-more":
        showHelpSheet = true
    default:
        break
    }
}

Groupes de conseils

Utilisez TipGroup pour coordonner plusieurs conseils dans une seule vue. TipGroup garantit qu'un seul conseil du groupe s'affiche à la fois, évitant la surcharge de conseils. Les conseils s'affichent par ordre de priorité.

struct OnboardingView: View {
    let tipGroup = TipGroup(.ordered) {
        WelcomeTip()
        NavigationTip()
        ProfileTip()
    }

    var body: some View {
        VStack {
            if let currentTip = tipGroup.currentTip {
                TipView(currentTip)
            }

            Button("Suivant") {
                tipGroup.currentTip?.invalidate(reason: .actionPerformed)
            }
        }
    }
}

Options de priorité

InitialiseurComportement
.orderedLes conseils s'affichent dans l'ordre dans lequel ils sont listés

Lorsque le conseil actuel est invalidé, le prochain conseil éligible du groupe devient currentTip.

Contrôle programmatique

Invalidation des conseils

Appelez invalidate(reason:) lorsque l'utilisateur effectue l'action découverte ou lorsque le conseil n'est plus pertinent.

let tip = FavoriteTip()
tip.invalidate(reason: .actionPerformed)
RaisonQuand l'utiliser
.actionPerformedL'utilisateur a effectué l'action que le conseil décrit
.displayCountExceededLe conseil a atteint son nombre d'affichage maximum
.tipClosedL'utilisateur a explicitement rejeté le conseil

Utilitaires de test

TipKit fournit des méthodes statiques pour contrôler la visibilité des conseils pendant le développement et les tests. Protégez-les avec #if DEBUG ou des vérifications ProcessInfo afin qu'elles ne s'exécutent jamais dans les builds de production.

#if DEBUG
// Afficher tous les conseils, quelles que soient les règles (utile pendant le développement)
Tips.showAllTipsForTesting()

// Afficher uniquement des conseils spécifiques
Tips.showTipsForTesting([FavoriteTip.self, ShortcutTip.self])

// Masquer tous les conseils (utile pour les tests UI qui n'impliquent pas de conseils)
Tips.hideAllTipsForTesting()

// Réinitialiser le magasin de données (efface tout l'état des conseils, invalidations et événements)
try? Tips.resetDatastore()
#endif

Utilisation de ProcessInfo pour les schémas de test

if ProcessInfo.processInfo.arguments.contains("--show-all-tips") {
    Tips.showAllTipsForTesting()
}

Passez --show-all-tips comme argument de lancement dans le schéma Xcode pour les builds de développement.

Erreurs courantes

NE FAITES PAS : Appeler Tips.configure() ailleurs que dans App.init

Appeler Tips.configure() dans un modificateur onAppear ou task d'une vue crée une situation de compétition où les vues de conseils tentent de s'afficher avant que le magasin de données ne soit prêt, provoquant des conseils manquants ou clignotants.

// FAUX
struct ContentView: View {
    var body: some View {
        Text("Bonjour")
            .task { try? Tips.configure() }  // Trop tard, les vues sont déjà rendues
    }
}

// CORRECT
@main struct MyApp: App {
    init() { try? Tips.configure() }
    var body: some Scene { WindowGroup { ContentView() } }
}

NE FAITES PAS : Afficher trop de conseils à la fois

L'affichage de plusieurs conseils simultanément submerge les utilisateurs et dilue l'impact de chaque conseil. Les utilisateurs apprennent à les ignorer.

// FAUX : Trois conseils visibles en même temps
VStack {
    TipView(tipA)
    TipView(tipB)
    TipView(tipC)
}

// CORRECT : Utiliser TipGroup pour les séquencer
let group = TipGroup(.ordered) { TipA(); TipB(); TipC() }
if let currentTip = group.currentTip {
    TipView(currentTip)
}

NE FAITES PAS : Oublier d'invalider les conseils après que l'utilisateur a effectué l'action

Si un conseil dit "Appuyez sur l'étoile pour ajouter aux favoris" et que l'utilisateur appuie sur l'étoile mais que le conseil reste, cela érode la confiance dans l'interface utilisateur.

// FAUX : Le conseil reste visible après l'action de l'utilisateur
Button("Favori") { toggleFavorite() }
    .popoverTip(favoriteTip)

// CORRECT : Invalider sur action
Button("Favori") {
    toggleFavorite()
    favoriteTip.invalidate(reason: .actionPerformed)
}
.popoverTip(favoriteTip)

NE FAITES PAS : Laisser les conseils de test activés en production

Tips.showAllTipsForTesting() contourne toutes les règles et limites de fréquence. Expédier cela en production signifie que chaque utilisateur voit immédiatement tous les conseils.

// FAUX : Toujours actif
Tips.showAllTipsForTesting()

// CORRECT : Protégé par DEBUG
#if DEBUG
Tips.showAllTipsForTesting()
#endif

NE FAITES PAS : Rendre les titres des conseils trop longs

Les titres longs sont tronqués ou s'enroulent de manière maladroite dans la légende compacte du conseil. Mettez l'action clé dans le titre et le contexte d'accompagnement dans le message.

// FAUX
var title: Text { Text("Vous pouvez appuyer sur le bouton en forme de cœur pour enregistrer cet élément dans votre liste de favoris") }

// CORRECT
var title: Text { Text("Enregistrer dans les favoris") }
var message: Text? { Text("Appuyez sur l'icône en forme de cœur pour conserver les éléments et y accéder rapidement.") }

NE FAITES PAS : Utiliser des conseils pour des informations critiques

Les utilisateurs peuvent rejeter les conseils à tout moment et ils ne réapparaissent pas. Ne placez jamais d'instructions essentielles ou d'informations de sécurité dans un conseil.

// FAUX : Informations critiques dans un conseil pouvant être rejeté
struct DataLossTip: Tip {
    var title: Text { Text("Les modifications non enregistrées seront perdues") }
}

// CORRECT : Utiliser une alerte ou un avertissement en ligne pour les informations critiques
// Réservez les conseils pour la découverte de fonctionnalités et la divulgation progressive

Liste de vérification pour la révision

  • Tips.configure() appelé dans App.init, avant le rendu des vues
  • Chaque conseil a un titre clair et concis (orienté action, moins de ~40 caractères)
  • Conseils invalidés lorsque l'utilisateur effectue l'action découverte
  • Règles définies pour que les conseils apparaissent au bon moment (pas immédiatement au premier lancement pour tous les conseils)
  • TipGroup utilisé lorsqu'il existe plusieurs conseils dans une vue
  • Utilitaires de test (showAllTipsForTesting, resetDatastore) protégés par #if DEBUG
  • Synchronisation CloudKit configurée si l'application prend en charge plusieurs appareils
  • Fréquence d'affichage définie de manière appropriée (.daily ou .weekly pour la plupart des applications)
  • Conseils utilisés uniquement pour la découverte de fonctionnalités, pas pour des informations critiques
  • TipViewStyle personnalisé appliqué de manière cohérente si le style par défaut ne correspond pas à la conception de l'application
  • Actions des conseils gérées et conseil invalidé dans le gestionnaire d'actions
  • Dons d'événements placés aux points d'action utilisateur corrects
  • Assurez-vous que les types Tip personnalisés sont Sendable ; configurez Tips sur @MainActor

Références

  • Voir references/tipkit-patterns.md pour les modèles d'implémentation complets incluant les styles personnalisés, les règles basées sur les événements, les groupes de conseils, les stratégies de test, les flux d'intégration et la configuration des aperçus SwiftUI.

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

JordanCoin/ios-skills-collection

Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries. Use when the user asks about GitHub issues, pull requests, workflows, or wants to interact with GitHub repositories from the command line — including tasks like check CI status, create PR, list issues, or query the GitHub API.

JordanCoin/ios-skills-collection

Create media playback experiences using AVKit. Use when adding video players with AVPlayerViewController, enabling Picture-in-Picture, routing media with AirPlay, using SwiftUI VideoPlayer views, configuring transport controls, displaying subtitles and closed captions, or integrating AVFoundation playback with system UI.

JordanCoin/ios-skills-collection

Integrate and optimize Core ML models in iOS apps for on-device machine learning inference. Covers model loading (.mlmodelc, .mlpackage), predictions with auto-generated classes and MLFeatureProvider, compute unit configuration (CPU, GPU, Neural Engine), MLTensor, VNCoreMLRequest, MLComputePlan, multi-model pipelines, and deployment strategies. Use when loading Core ML models, making predictions, configuring compute units, or profiling model performance.

JordanCoin/ios-skills-collection

Implement, review, or improve maps and location features in iOS/macOS apps using MapKit and CoreLocation. Use when working with Map views, annotations, markers, polylines, user location tracking, geocoding, reverse geocoding, search/autocomplete, directions and routes, geofencing, region monitoring, CLLocationUpdate async streams, or location authorization flows. Also use when working with maps, coordinates, addresses, places, directions, distance calculations, or location-based features in Swift apps.

JordanCoin/ios-skills-collection

Display and manipulate PDF documents using PDFKit. Use when embedding PDFView to show PDF files, creating or modifying PDFDocument instances, adding annotations (highlights, notes, signatures), extracting text with PDFSelection, navigating pages, generating thumbnails, filling PDF forms, or wrapping PDFView in SwiftUI.

JordanCoin/ios-skills-collection

When the user wants to optimize their Google Play Store listing — title, short description, full description, keywords, ratings, or Play Store-specific features. Use when the user mentions "Google Play", "Android", "Play Store", "Play Console", "short description", "full description indexed", "Google Play ASO", or wants Google Play-specific keyword, creative, or ratings strategy. For iOS App Store optimization, see aso-audit and metadata-optimization.

JordanCoin/ios-skills-collection

When the user wants to implement, optimize, or use App Clips for app discovery and conversion. Use when the user mentions "App Clip", "app clip code", "mini app", "instant app", "App Clip card", "App Clip link", "no download required", "instant experience", or wants to understand how App Clips appear in App Store search. For general App Store discoverability, see aso-audit. For marketing campaigns, see ua-campaign.

JordanCoin/ios-skills-collection

When the user wants to plan a launch strategy for a new app or major update. Also use when the user mentions "app launch", "launch plan", "launch checklist", "pre-launch", "launch day", or "how to launch my app". For ongoing ASO after launch, see aso-audit. For paid acquisition during launch, see ua-campaign.

JordanCoin/ios-skills-collection

When the user wants to analyze their own app's actual performance data from App Store Connect — real downloads, revenue, IAP, subscriptions, trials, or country breakdowns synced via Appeeky Connect. Use when the user asks about "my downloads", "my revenue", "how is my app performing", "ASC data", "sales and trends", "my subscription numbers", "App Store Connect metrics", or wants to compare periods or top markets. For third-party app estimates, see app-analytics. For subscription analytics depth, see monetization-strategy.

JordanCoin/ios-skills-collection

When the user wants a full ASO health audit, review their App Store listing quality, or diagnose why their app isn't ranking. Also use when the user mentions "ASO audit", "ASO score", "why am I not ranking", "listing review", or "optimize my app store page". For keyword-specific research, see keyword-research. For metadata writing, see metadata-optimization.

JordanCoin/ios-skills-collection

Always use when working on any iOS, macOS, Swift, SwiftUI, Xcode, or Apple platform project. Routes to the correct specialized skills based on development phase and task context. This collection contains 210 skills from 28 authors covering the full iOS lifecycle.

Skills associés