← Tous les articles

App Intents 2.0 dans iOS 26 : Visual Intelligence, snippets interactifs et propriétés différées

App Intents est apparu dans iOS 16 comme l’API d’actions structurées d’Apple pour Shortcuts, Siri et Spotlight ; iOS 17 l’a étendu pour les widgets pilotés par App Intents ; iOS 18 en a fait le contrat pour la surface d’action d’Apple Intelligence. iOS 26 étend App Intents à Visual Intelligence (résultats de recherche d’images depuis des applications tierces), aux snippets interactifs (petites fenêtres pop-up qui s’intègrent dans les contextes système), aux annotations de vue d’entité (la façon dont une entité s’affiche en ligne) et à @DeferredProperty (propriétés d’entité calculées de manière asynchrone)1. Ces extensions ne modifient pas le modèle de base d’App Intents ; elles ajoutent de nouvelles surfaces de participation qu’une application peut adopter.

Cet article passe en revue les ajouts d’iOS 26 à la lumière de la documentation d’Apple. Le cadre est « quelles nouvelles surfaces une adoption existante d’App Intents gagne-t-elle en ajoutant les conformances d’iOS 26 », car la plupart des applications dotées d’App Intents disposent déjà des types fondamentaux, et le travail d’iOS 26 consiste à étendre ces types à de nouveaux contextes.

TL;DR

  • IntentValueQuery est le nouveau protocole pour l’intégration à Visual Intelligence. La requête accepte un SemanticContentDescriptor (le contexte visuel de l’utilisateur) et renvoie un tableau d’instances AppEntity que l’application juge pertinentes2.
  • @DeferredProperty déclare une propriété d’entité dont la valeur est calculée de manière asynchrone. La propriété se charge lorsque le système en a réellement besoin, évitant ainsi un coût initial pour les entités comportant de nombreux champs peu coûteux à afficher et quelques champs coûteux à calculer.
  • Les snippets interactifs d’App Intents permettent à une application de présenter une petite fenêtre pop-up (avec boutons, texte, contrôles) à l’intérieur de contextes système comme Spotlight, Visual Intelligence ou la surface de réponse de Siri. Le snippet est une vue SwiftUI liée au résultat de l’App Intent.
  • Les annotations de vue d’entité permettent à une application de déclarer comment un AppEntity doit s’afficher dans différents contextes système (une ligne compacte dans Spotlight, une carte vedette dans Visual Intelligence, un widget de type Live Activity).
  • L’article App Intents du cluster couvrait le modèle fondamental ; cet article l’étend aux nouvelles surfaces de participation d’iOS 26. L’article App Intents vs MCP Tools du cluster aborde la question du routage entre la surface d’intention d’Apple Intelligence et les MCP tools d’agents généralistes.

Visual Intelligence : IntentValueQuery et SemanticContentDescriptor

L’ajout phare d’iOS 26 à App Intents est l’intégration à Visual Intelligence2. Le flux :

  1. L’utilisateur prend une photo, capture une capture d’écran ou pointe l’appareil photo vers un objet.
  2. La couche Visual Intelligence du système extrait le contexte visuel et sémantique (ce qui figure dans l’image, ce que l’utilisateur pourrait souhaiter à son sujet).
  3. Le système interroge chaque application ayant enregistré un IntentValueQuery avec ce contexte sémantique.
  4. Chaque application renvoie les instances AppEntity pertinentes ; le système les agrège et les présente dans l’interface de Visual Intelligence.
  5. L’utilisateur tape sur une entité pour entrer dans l’application d’origine au bon contexte.

La surface développeur est une struct conforme à IntentValueQuery avec une méthode values(for:) qui prend un SemanticContentDescriptor :

import AppIntents

struct ProductLookupQuery: IntentValueQuery {
    func values(for descriptor: SemanticContentDescriptor) async throws -> [Product] {
        // descriptor.labels: detected category and content labels
        // descriptor.pixelBuffer: the visual content as a CVReadOnlyPixelBuffer
        //                        (use VideoToolbox/CoreImage to convert if needed)
        let candidates = try await catalog.search(labels: descriptor.labels)
        return candidates.map(Product.init)
    }
}

Le SemanticContentDescriptor transporte deux champs renseignés par le système : labels (un tableau de balises de catégorie et de contenu détectées telles que « bouteille de vin », « pinot noir », « texte d’étiquette », etc.) et pixelBuffer (les données d’image sous-jacentes sous forme de CVReadOnlyPixelBuffer pour les applications souhaitant exécuter leurs propres modèles de vision sur le contenu). Le rôle de l’application est de mapper ces signaux à ses propres données et de renvoyer les entités correspondantes.

Le bon schéma d’adoption : une application de shopping implémente la requête contre son catalogue de produits (contexte visuel → produits correspondants), une application de vins contre sa base de données de bouteilles (image d’étiquette → entrée de vin), une application de recettes contre sa bibliothèque de recettes (photo d’ingrédient → recettes correspondantes).

@DeferredProperty : valeurs d’entité asynchrones

Les types AppEntity existants déclarent leurs propriétés de manière statique. Chaque propriété doit être calculée avant que l’entité ne soit renvoyée. Pour les entités aux propriétés à coûts mixtes (titre/sous-titre/image rapides, description détaillée lente provenant du serveur), le calcul tout-ou-rien est gaspilleur.

@DeferredProperty (iOS 26+) déclare une propriété comme calculée de manière asynchrone3 :

import AppIntents

struct Recipe: AppEntity {
    static var typeDisplayRepresentation = TypeDisplayRepresentation(...)
    static var defaultQuery = RecipeQuery()

    @Property(title: "Title")
    var title: String

    @Property(title: "Cuisine")
    var cuisine: String

    @DeferredProperty(title: "Detailed Instructions")
    var instructions: String {
        get async throws {
            try await loadInstructionsFromBackend(id: id)
        }
    }
}

L’accesseur de la propriété différée est asynchrone ; il ne s’exécute que lorsque le système a réellement besoin de la valeur (par exemple, lorsque l’entité est sélectionnée pour un affichage détaillé). Pour les entités renvoyées par une requête et utilisées uniquement pour l’interface de sélection, la propriété différée n’est jamais calculée.

Le motif convient à toute entité comportant des champs rapides à construire (id, titre, résumé) en plus de champs coûteux à construire (corps complet, métriques calculées, données récupérées sur le serveur). Sans @DeferredProperty, le développeur calcule soit tout (gaspilleur) soit uniquement les champs peu coûteux et ajoute un intent « charger les détails » distinct (plus complexe).

Snippets interactifs et SnippetIntent

iOS 26 introduit le protocole dédié SnippetIntent pour les interactions en forme de snippet, aux côtés du modèle existant d’AppIntent conforme à ShowsSnippetView issu des versions antérieures4. SnippetIntent ajoute une méthode statique reload() que le système peut appeler pour rafraîchir le contenu du snippet sans réinvocation complète de l’intent :

struct WeatherSnippet: SnippetIntent {
    static var title: LocalizedStringResource = "Weather Snippet"

    @Parameter(title: "City")
    var city: City

    func perform() async throws -> some IntentResult & ShowsSnippetView {
        let forecast = try await weatherService.forecast(for: city)
        return .result(view: ForecastSnippet(forecast: forecast))
    }

    static func reload() async throws {
        // Triggered by the system when it wants fresh snippet data
        // (e.g., after the data source signals an update)
    }
}

Pour les intents non spécifiquement de type snippet qui souhaitent attacher une vue snippet à leur réponse, le modèle existant AppIntent + ShowsSnippetView fonctionne toujours :

struct WeatherForecastIntent: AppIntent {
    static var title: LocalizedStringResource = "Weather Forecast"

    @Parameter(title: "City")
    var city: City

    func perform() async throws -> some IntentResult & ProvidesDialog & ShowsSnippetView {
        let forecast = try await weatherService.forecast(for: city)

        return .result(
            dialog: "Here's the forecast for \(city.name).",
            view: ForecastSnippet(forecast: forecast)
        )
    }
}

struct ForecastSnippet: View {
    let forecast: Forecast
    var body: some View {
        VStack(alignment: .leading) {
            Text(forecast.headline).font(.headline)
            HStack {
                ForEach(forecast.days) { day in
                    DayCell(day: day)
                }
            }
            Button("Open in App") {
                // App-launching action wired via App Intents
            }
        }
        .padding()
    }
}

La conformance ShowsSnippetView du type de résultat indique au système d’afficher la vue SwiftUI aux côtés du dialogue. Le snippet est interactif : les boutons à l’intérieur peuvent déclencher d’autres App Intents, l’utilisateur peut faire défiler, la vue participe à la couche d’interaction du système.

Les cas qui justifient un snippet interactif : prévisions météorologiques, événements de calendrier, horaires de transport, scores sportifs, suivi de colis. Partout où l’utilisateur souhaite plus qu’une réponse de dialogue d’une seule ligne depuis la surface système.

Annotations de vue d’entité

Les annotations de vue d’entité permettent à une application de déclarer comment un AppEntity doit s’afficher dans différents contextes système5. Le mécanisme étend DisplayRepresentation avec plusieurs variantes :

struct Recipe: AppEntity {
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "\(title)",
            subtitle: "\(cuisine) - \(time) min",
            image: .init(named: imageName)
        )
    }
}

Le modèle classique renvoie une seule DisplayRepresentation. iOS 26 permet aux entités de fournir des variantes spécifiques au contexte parmi lesquelles le système choisit en fonction de l’endroit où il effectue le rendu (liste compacte, carte vedette, résultat Spotlight, panneau Visual Intelligence). Le framework choisit la bonne variante pour chaque contexte ; l’application déclare chacune d’entre elles.

Le motif prend en charge les applications qui ont besoin que le rendu d’entité diffère, par exemple, entre une liste Spotlight densément remplie et une réponse Visual Intelligence à carte unique. Les variantes se composent sans que l’application n’ait à détecter le contexte.

Composition avec App Intents existant

Les ajouts d’iOS 26 se composent avec les primitives App Intents existantes :

  • L’AppShortcutsProvider d’une application (couvert dans Accessibility as platform) enregistre les raccourcis pour la voix, le bouton d’action et Spotlight.
  • Chaque AppShortcut référence un AppIntent, qui possède des propriétés @Parameter résolues à partir de la requête de l’utilisateur.
  • La méthode AppIntent.perform() renvoie un type de résultat pouvant inclure une vue snippet (ShowsSnippetView) ou un dialogue (ProvidesDialog).
  • Les types AppEntity référencés par les paramètres de l’intent prennent désormais en charge @DeferredProperty et les annotations de vue d’entité.
  • Les nouveaux types IntentValueQuery permettent aux mêmes entités d’apparaître dans Visual Intelligence.

La forme : le modèle existant est préservé ; le travail d’iOS 26 consiste à ajouter de nouveaux types (requêtes) et de nouvelles annotations (différées, variantes de vue) à la même surface d’entité.

Échecs courants

Trois schémas issus des échecs d’adoption d’App Intents 2.0 :

IntentValueQuery renvoyant des résultats non délimités. Une requête qui renvoie tous les produits correspondant aux termes de recherche du descripteur, indépendamment de leur pertinence, dilue l’expérience Visual Intelligence. Correctif : délimiter la requête (top-N en pertinence, pondérée par récence, personnalisée par utilisateur) afin que chaque entité renvoyée mérite sa place dans l’interface du système.

@DeferredProperty pour des valeurs rapides. Le mécanisme différé est destiné à des calculs réellement coûteux. Marquer une propriété rapide en mémoire comme différée ajoute une surcharge asynchrone sans bénéfice. Correctif : réservez @DeferredProperty aux propriétés qui rentabilisent réellement le report (récupérations sur serveur, calculs lourds, invocations de modèles ML).

Snippets interactifs qui sont des applications complètes. Un snippet est une surface d’interface compacte ; le traiter comme une mini-application produit des snippets qui semblent à l’étroit ou lents au rendu. Correctif : gardez les snippets concentrés sur la réponse immédiate et une ou deux actions connexes ; utilisez le bouton « Open in App » pour transférer les flux complexes vers l’application complète.

Ce que ce schéma signifie pour les applications iOS 26+

Trois enseignements.

  1. Ajoutez IntentValueQuery à toute application avec du contenu visuel. Shopping, recettes, produits, lieux, objets identifiables. L’intégration à Visual Intelligence est la nouvelle surface de découverte ; les applications qui n’y participent pas y sont invisibles.

  2. Utilisez @DeferredProperty pour les champs d’entité coûteux. Descriptions détaillées, métriques calculées, données récupérées sur serveur. Le modèle async par défaut correspond au code Swift moderne et préserve la rapidité des retours d’entités peu coûteuses à construire.

  3. Adoptez les snippets interactifs pour les types de requêtes à forte valeur. Météo, calendrier, transports, sports, suivi de colis. L’interface snippet maintient les utilisateurs sur la surface de réponse système pour les cas où un dialogue d’une ligne est insuffisant mais où le lancement complet de l’application est excessif.

Le cluster Apple Ecosystem complet : App Intents typé ; serveurs MCP ; la question du routage ; Foundation Models ; la distinction LLM runtime vs outillage ; trois surfaces ; le motif de source unique de vérité ; Two MCP Servers ; hooks pour le développement Apple ; Live Activities ; le contrat runtime watchOS ; les internes de SwiftUI ; le modèle mental spatial de RealityKit ; la discipline de schéma SwiftData ; les motifs Liquid Glass ; l’expédition multi-plateforme ; la matrice des plateformes ; le framework Vision ; les Symbol Effects ; l’inférence Core ML ; l’API Writing Tools ; Swift Testing ; le Privacy Manifest ; Accessibility as platform ; la typographie SF Pro ; les motifs spatiaux visionOS ; le framework Speech ; les migrations SwiftData ; le moteur de focus tvOS ; les internes de @Observable ; le protocole Layout SwiftUI ; les SF Symbols personnalisés ; AVFoundation HDR ; le cycle de vie d’entraînement watchOS ; ce que je refuse d’écrire. Le hub se trouve sur la série Apple Ecosystem. Pour un contexte iOS-avec-agents-IA plus large, consultez le guide iOS Agent Development.

FAQ

Dois-je activer Apple Intelligence pour tester IntentValueQuery ?

Pour des tests Visual Intelligence complets, oui. Visual Intelligence requiert un matériel compatible Apple Intelligence (iPhone 15 Pro ou plus récent, Mac M1 ou plus récent) avec iOS 26+ et Apple Intelligence activé. Pour le développement, vous pouvez tester la requête dans des tests unitaires en construisant directement un SemanticContentDescriptor et en appelant la méthode values(for:) de la requête sans la pile système complète.

@DeferredProperty peut-il lancer une exception ?

Oui. La signature de l’accesseur asynchrone est get async throws, et les exceptions se propagent jusqu’au système. Le système gère l’échec en affichant l’entité sans la valeur de la propriété différée (ou en montrant un état d’erreur dans certains contextes). Les applications doivent échouer avec élégance et renvoyer des états d’erreur significatifs plutôt que de planter.

Le contenu des snippets interactifs prend-il en charge les animations ?

Oui, avec les primitives d’animation SwiftUI standard. La vue du snippet s’exécute dans la surface de réponse du système, qui prend en charge la même infrastructure d’animation qu’en SwiftUI in-app. Reportez-vous à l’article Symbol Effects du cluster pour le vocabulaire d’animation correspondant aux conventions de la plateforme.

Comment les annotations de vue d’entité interagissent-elles avec les widgets ?

Les widgets sont une surface WidgetKit distincte ; les annotations de vue d’entité s’appliquent dans les contextes App Intents (Spotlight, Visual Intelligence, réponses Siri). Pour une application qui expose les mêmes données à la fois sous forme d’AppEntity et de widget, les deux surfaces requièrent des déclarations d’interface distinctes. Les applications partagent généralement le modèle de données sous-jacent et écrivent des vues de présentation légères par surface.

Quelle est la relation entre cela et les MCP tools ?

Les App Intents sont la surface d’intention d’Apple Intelligence ; les MCP tools sont le protocole agent-serveur pour les LLMs généralistes. iOS 26 ajoute Visual Intelligence à App Intents (la surface d’Apple). Pour les agents non-Apple (Claude, classe GPT), les MCP tools s’exécutant en local ou à distance couvrent le même territoire conceptuel. L’article App Intents vs MCP Tools du cluster aborde la question du routage.

IntentValueQuery peut-il être combiné avec EntityQuery ?

Oui. Ils servent des surfaces différentes : EntityQuery est destiné aux cas où l’utilisateur tape ou prononce un nom d’entité (Spotlight, Siri) ; IntentValueQuery est destiné aux cas où l’utilisateur se trouve dans Visual Intelligence avec un contexte d’image. L’AppEntity d’une application peut avoir les deux requêtes enregistrées ; le système choisit la bonne pour le contexte.

Références


  1. Documentation développeur Apple : App Intents. La référence du framework couvrant AppIntent, AppEntity, les requêtes, les paramètres et les ajouts d’iOS 26. 

  2. Apple Developer : Explore new advances in App Intents (session WWDC 2025 numéro 275). L’introduction d’IntentValueQuery, de SemanticContentDescriptor et de l’intégration à Visual Intelligence. 

  3. Documentation développeur Apple : @DeferredProperty(). La macro de propriété d’entité calculée de manière asynchrone introduite pour les App Entities dans iOS 26. Présentation dans la session WWDC 2025 numéro 275 (Explore new advances in App Intents). 

  4. Documentation développeur Apple : Snippets interactifs d’App Intents via le type de résultat ShowsSnippetView combiné à des vues SwiftUI qui s’affichent dans des contextes système (Spotlight, Visual Intelligence, zone de réponse Siri). 

  5. Documentation développeur Apple : DisplayRepresentation et annotations de vue d’entité. Le mécanisme permettant de déclarer comment un AppEntity s’affiche dans différents contextes système. 

Articles connexes

App Intents vs MCP: The Routing Question

Two protocols, one app. App Intents expose your app to Apple Intelligence. MCP exposes the same domain to Claude, ChatGP…

16 min de lecture

Three Surfaces: Human, Apple Intelligence, Agent

Every iOS app capability faces three surfaces: human, Apple Intelligence, agent. Each has different obligations, renderi…

17 min de lecture

The Cleanup Layer Is the Real AI Agent Market

Charlie Labs pivoted from building agents to cleaning up after them. The AI agent market is moving from generation to pr…

15 min de lecture