Développeurs
App Intents dans iOS 27 : Siri, App Schemas et index sémantique
App Intents et Siri dans iOS 27 : App Schemas, IndexedEntity et index sémantique, contexte à l'écran et IntentValueRepresentation, y compris sur iPhone Duo.
Par la rédaction AppleDuoPublié le 8 min de lecture
Sur cette page
- Que sont les App Intents dans iOS 27 ?
- Comment les App Schemas et les domaines aident-ils Siri à comprendre votre app ?
- Comment rendre le contenu de mon app trouvable par Siri ?
- Que faire si mon contenu ne peut pas être indexé ?
- Comment Siri sait-il ce qui est affiché à l'écran de mon app ?
- Comment partager des données avec d'autres apps via Siri ?
- Qu'est-ce qui change pour Siri sur iPhone Duo ?
- Ce qu'il faut retenir
Dans iOS 27, Siri peut trouver du contenu dans les apps, agir dessus et comprendre ce qui est affiché à l'écran. Rien de tout cela ne se produit si votre app ne se décrit pas d'une manière que Siri sait lire. Cette description, c'est App Intents : le framework qui alimente déjà Raccourcis et les actions Spotlight, étendu dans iOS 27 avec les App Schemas, l'index sémantique et de nouveaux moyens de partager des données entre apps. Ce guide passe en revue chaque élément, dans l'ordre d'adoption recommandé par Apple.
Cet article s'appuie sur les sessions et la documentation WWDC26 d'Apple, un article de Jordan Morgan et les publications du développeur iOS @sarunw. L'équipe AppleDuo n'a pas livré ce code en production. Plusieurs API sont nouvelles dans iOS 27 et Xcode 27, d'autres remontent à iOS 18 ou iOS 26, et certains détails peuvent changer d'une version à l'autre.
Que sont les App Intents dans iOS 27 ?
Comme le résume @sarunw, un App Intent est une action que votre app sait faire. Une fois défini, il est disponible dans tout le système : Raccourcis, Spotlight et widgets. Dans la session WWDC26 Build intelligent Siri experiences with App Schemas, Apple présente App Intents comme la base de l'intégration avec Siri et Apple Intelligence.
Un intent de base comporte un titre et une méthode perform(). Cette forme existe depuis iOS 16 :
struct OpenInboxIntent: AppIntent {
static var title: LocalizedStringResource = "Open Inbox"
static var openAppWhenRun = true
func perform() async throws -> some IntentResult {
// Naviguer vers la boîte de réception
return .result()
}
}
La nouveauté d'iOS 27, c'est jusqu'où Siri peut pousser ces actions. Selon Apple, Siri se charge de la compréhension du langage pendant que votre app se concentre sur l'action. Pour que cette répartition fonctionne, Siri doit savoir ce que signifie chaque action et chaque élément de contenu.
Comment les App Schemas et les domaines aident-ils Siri à comprendre votre app ?
@sarunw le résume en trois éléments. Les App Intents décrivent l'action. Les App Schemas lui donnent un sens que Siri comprend. Les domaines regroupent les schemas liés.
Apple décrit les schemas comme une spécialisation des App Intents : ce sont toujours des App Intents, mais structurés pour que Siri sache comment les traiter. Vous en appliquez un avec une macro placée avant la déclaration : AppIntent(schema:), AppEntity(schema:) ou AppEnum(schema:). La page App schema domains d'Apple liste trois groupes :
| Groupe de domaines | Exemples | Fonctionne avec |
|---|---|---|
| Domaines principaux | Audio, Calendar, Camera, Clock, Mail, Maps, Messages, Notes, Phone, Photos, Reminders, System et recherche dans l'app | Apple Intelligence et Siri |
| Domaines à usage unique | Assistant, Visual intelligence | Une surface système précise |
| Domaines propres à Raccourcis | Books, Browser, Files, Journaling, Presentation, Reader, Spreadsheet, Whiteboard, Word processor | Raccourcis uniquement, pas Siri |
Les domaines de schemas sont apparus avec iOS 18. Dans la session WWDC26, l'app de messagerie d'exemple d'Apple adopte le schema sendMessage du domaine Messages. Xcode 27 vérifie aussi les schemas liés à la compilation : adoptez sendMessage sans draftMessage et vous obtenez une erreur de compilation avec un Fix-It qui génère le squelette.
Si votre contenu ne correspond à aucun schema, vous pouvez toujours livrer de simples App Intents. L'article de Jordan Morgan sur iOS 27 note qu'on ne sait pas encore dans quelle mesure le nouveau comportement de Siri profite aux apps hors schema.
Comment rendre le contenu de mon app trouvable par Siri ?
Les actions ne sont que la moitié de l'histoire ; Siri doit aussi trouver la chose dont parle l'utilisateur. @sarunw liste quatre étapes, qui suivent l'ordre de la session d'Apple :
| Étape | API | Pourquoi |
|---|---|---|
| 1. Décrire le contenu | AppEntity | Indique ce qu'est un élément, comment il est identifié et quelles propriétés comptent |
| 2. Lui donner un sens | @AppEntity(schema:) | Indique à Siri de quel type de contenu il s'agit |
| 3. L'indexer | IndexedEntity | Place les entités dans l'index sémantique du système |
| 4. Prévoir un repli | EntityStringQuery | Trouve le contenu que vous ne pouvez pas indexer à l'avance |
Les étapes 2 et 3 se retrouvent dans une seule déclaration. Voici l'entité de message de la session WWDC26 d'Apple :
@AppEntity(schema: .messages.message)
struct MessageEntity: IndexedEntity {
// Le contenu textuel du message
@Property(indexingKey: \.textContent)
var body: AttributedString?
}
@sarunw la décompose en trois décisions : le type de contenu, le fait qu'il doit être indexé, et le champ à indexer. Apple indique qu'adopter IndexedEntity est le principal moyen d'assurer la résolution des entités, car les entités indexées entrent dans l'index sémantique, ce qui permet à Siri de les faire correspondre par leur sens plutôt que par des mots exacts.
La partie indexingKey est une traduction. Comme l'explique @sarunw, votre propriété s'appelle body, mais Spotlight stocke sa valeur sous textContent. Sans cette correspondance, le système n'a aucun moyen de savoir lequel de vos champs contient le texte du message.
Qu'est-ce qui est nouveau ?
IndexedEntity est arrivé avec iOS 18, et @Property(indexingKey:) avec iOS 26, selon la page App Intents updates d'Apple. Ce qu'apporte iOS 27, c'est l'utilisation de cet index par Siri pour la correspondance sémantique, ainsi que de nouveaux types comme IndexedEntityQuery. Dans la session code-along, Apple maintient aussi l'index à jour en appelant indexAppEntities sur un CSSearchableIndex après la création ou la mise à jour de contenu, et deleteAppEntities après sa suppression.
Que faire si mon contenu ne peut pas être indexé ?
Certains contenus ne peuvent pas être indexés à l'avance : ils résident sur un serveur, changent en permanence ou sont trop volumineux. Pour ces cas, Apple renvoie vers EntityStringQuery. Siri transmet à votre app les mots de l'utilisateur, et votre app renvoie les entités correspondantes. Voici l'exemple d'Apple :
struct ContactQuery: EntityStringQuery {
func entities(matching string: String) async throws -> [ContactEntity] {
let predicate = #Predicate<Person> { person in
person.name.localizedStandardContains(string)
}
let descriptor = FetchDescriptor<Person>(predicate: predicate)
let matches = try modelContext.fetch(descriptor)
return matches.map(\.entity)
}
}
Une requête par chaîne fait correspondre du texte, pas du sens, et elle exécute votre code à chaque demande. Préférez IndexedEntity partout où c'est possible et gardez les requêtes par chaîne pour le reste.
Comment Siri sait-il ce qui est affiché à l'écran de mon app ?
@sarunw note que dans iOS 27, Siri peut lire ce qui est affiché à l'écran, mais que vous devez lui indiquer quelle App Entity représente une vue. L'article d'Apple Providing contextual cues to Apple Intelligence and Siri décrit deux approches, et la session WWDC26 donne la règle : utilisez une user activity quand un seul élément principal est à l'écran, et des annotations de vue quand plusieurs éléments significatifs sont visibles.
Pour une liste, appliquez appEntityIdentifier(_:) à chaque ligne :
List {
ForEach(messages) { message in
MessageRow(message: message)
.appEntityIdentifier(
EntityIdentifier(
for: MessageEntity.self,
identifier: message.id
)
)
}
}
Quand un seul élément occupe l'écran, annotez-le avec un NSUserActivity et définissez la propriété appEntityIdentifier de l'activité. En SwiftUI, le modificateur userActivity vous donne l'activité à configurer. Le code-along d'Apple applique .userActivity avec un EntityIdentifier à sa vue de détail d'événement sans afficher le code ; voici donc notre ébauche :
EventDetailView(event: event)
.userActivity("com.example.viewEvent") { activity in
activity.title = event.title
activity.appEntityIdentifier = EntityIdentifier(
for: EventEntity.self,
identifier: event.id
)
}
Ces deux API existaient avant iOS 27 : la documentation d'Apple indique le modificateur SwiftUI à partir d'iOS 18.4 et la propriété de NSUserActivity à partir d'iOS 18.2. Apple met aussi en garde contre l'association d'entités sans rapport : une annotation doit refléter les données que la vue affiche. Pour du contenu dessiné sur mesure sans une vue par entité, utilisez appEntityUIElements(_:).
Comment partager des données avec d'autres apps via Siri ?
Transferable est le protocole derrière ShareLink et le glisser-déposer. Dans iOS 27, Siri l'utilise aussi. Vous renvoyez une IntentValueRepresentation, et une seule conformité couvre les deux sens.
La raison est que les simples fichiers et données ont leurs limites. L'exemple d'Apple : Plans ne peut pas utiliser la photo d'un monument pour calculer un itinéraire jusqu'à lui. Pour les personnes, les lieux et les noms, IntentValueRepresentation (nouveau dans iOS 27) transmet un type système que les autres apps peuvent utiliser directement, comme IntentPerson, PlaceDescriptor ou PersonNameComponents. L'export, tiré de la session d'Apple :
extension ContactEntity: Transferable {
static var transferRepresentation: some TransferRepresentation {
IntentValueRepresentation(
exporting: \.person
)
}
}
Les valeurs entrantes suivent l'un de deux chemins. La règle d'Apple : résoudre le contenu qui existe déjà et importer celui qui n'existe pas. Comme le décrit @sarunw à propos d'IntentValueQuery, le système transmet la valeur entrante, et vous cherchez dans vos propres données pour renvoyer ce qui correspond :
struct ContactEntityQuery: IntentValueQuery {
func values(for input: [IntentPerson]) async throws -> [ContactEntity] {
let names = input.map(\.displayName)
let descriptor = FetchDescriptor<Contact>()
let contacts = try model.mainContext.fetch(descriptor)
let matches = contacts.filter { contact in
names.contains(where: { name in
contact.name.localizedStandardContains(name)
})
}
return matches.map(\.entity)
}
}
Quand rien ne correspond, créez le contenu avec IntentValueRepresentation(exporting:importing:), qui prend une closure construisant une nouvelle entité à partir de l'IntentPerson entrant. IntentValueQuery lui-même date d'iOS 26, où il a été introduit pour visual intelligence.
Une mise en garde : un développeur a signalé sur les forums que, sur une bêta d'iOS 27, les closures d'export ne s'exécutaient jamais et que Siri demandait des précisions à la place. Le fil n'a pas de réponse confirmée, alors testez sur la version finale.
Qu'est-ce qui change pour Siri sur iPhone Duo ?
Rien côté API. Nous n'avons trouvé aucune API Siri ou App Intents spécifique à l'iPhone Duo ; le code ci-dessus est le même sur tous les iPhone sous iOS 27.
Ce qui change, c'est l'espace d'affichage. Quand l'iPhone Duo est ouvert, l'écran intérieur renvoie des size classes regular dans les deux sens, si bien que beaucoup d'apps affichent à la fois une barre latérale, une liste et une vue de détail. Notre guide des size classes de l'iPhone Duo couvre ce changement de mise en page. Plus de contenu à l'écran, c'est plus d'éléments que Siri doit résoudre avec « celui-ci » ou « le troisième message », et plus d'endroits où une annotation manquante laisse Siri deviner.
Quelques vérifications pratiques :
- Annotez chaque colonne. Si une disposition en split affiche une liste à côté d'une vue de détail, donnez aux lignes de la liste un
appEntityIdentifieret à la vue de détail une user activity. - Liez les annotations aux données visibles. Quand l'appareil se plie et que votre mise en page change, les annotations doivent suivre les vues réellement affichées.
- Validez par étapes. Apple suggère le framework
AppIntentsTestingpour la logique, puis Raccourcis pour la forme des intents, Spotlight pour l'indexation et Siri pour le parcours complet.
Pour le reste du travail d'adaptation d'une app, utilisez notre checklist pour préparer votre app à l'iPhone Duo.
Ce qu'il faut retenir
- Les App Intents décrivent les actions ; les App Schemas, appliqués avec
@AppIntent(schema:)et@AppEntity(schema:), leur donnent un sens que Siri comprend ; les domaines regroupent les schemas. - Rendez le contenu trouvable en quatre étapes : App Entity, App Schema,
IndexedEntitypour l'index sémantique, etEntityStringQuerycomme solution de repli. @Property(indexingKey:)associe votre champ à celui de Spotlight, par exemplebodyàtextContent.- Pour que Siri comprenne ce qui est à l'écran, utilisez
appEntityIdentifiersur les lignes de liste etNSUserActivityquand un seul élément occupe l'écran. - Adoptez
TransferableavecIntentValueRepresentation(iOS 27) pour partager des données, etIntentValueQuerypour faire correspondre les valeurs entrantes. - L'iPhone Duo utilise les mêmes API ; son espace plus grand met simplement plus de contenu à annoter à l'écran.
Ensuite, préparez vos captures d'écran App Store pour l'iPhone Duo, ou parcourez les apps et jeux déjà conçus pour le pli.
Questions fréquentes
Que faut-il pour que mon app fonctionne avec Siri dans iOS 27 ?
Définissez vos actions comme des App Intents et votre contenu comme des App Entities, puis rendez-les conformes aux App Schemas d'un domaine correspondant, comme Messages ou Calendar. Les schemas indiquent à Siri ce que signifie un intent ou une entité, vous n'avez donc pas à écrire de phrases d'entraînement.
À quoi sert IndexedEntity pour Siri ?
Adopter IndexedEntity place vos app entities dans l'index sémantique du système, ce qui permet à Siri de les retrouver par leur sens plutôt que par des mots exacts. Apple en parle comme du principal moyen d'assurer la résolution des entités.
À quoi sert @Property(indexingKey:) ?
Il associe l'une des propriétés de votre entité à un attribut Spotlight. Par exemple, une propriété de message nommée body peut être indexée sous la clé textContent, pour que le système sache que ce champ contient le texte du message.
Comment Siri sait-il ce qui est affiché à l'écran de mon app ?
C'est vous qui le lui indiquez. Appliquez le modificateur appEntityIdentifier à chaque ligne d'une liste pour que chaque élément visible corresponde à une App Entity, ou associez un NSUserActivity doté d'un appEntityIdentifier quand un seul élément occupe l'écran.
Comment permettre à une autre app d'utiliser mes données via Siri ?
Rendez votre App Entity conforme à Transferable et renvoyez une IntentValueRepresentation qui exporte un type système comme IntentPerson. Pour accepter des valeurs entrantes, faites-les correspondre avec une IntentValueQuery, ou créez du nouveau contenu avec la variante d'import.
Existe-t-il une API Siri spécifique à l'iPhone Duo ?
Pas à notre connaissance. L'intégration à Siri utilise les mêmes API App Intents sur tous les iPhone. Sur le grand écran intérieur de l'iPhone Duo, davantage de contenu peut être affiché en même temps, donc annoter chaque élément visible compte encore plus.
Sources
- Build intelligent Siri experiences with App Schemas (WWDC26) · Apple Developer
- Code-along: Make your app available to Siri (WWDC26) · Apple Developer
- Providing contextual cues to Apple Intelligence and Siri · Apple Developer Documentation
- App schema domains · Apple Developer Documentation
- App Intents updates · Apple Developer Documentation
- appEntityIdentifier(_:) · Apple Developer Documentation
- iOS 27, Your App, and Siri · Swiftjective-C (Jordan Morgan)
- An App Intent is an action your app can do · @sarunw on X
- App Intents, App Schemas and domains · @sarunw on X
- Making your app's content findable by Siri, in four steps · @sarunw on X
- Three things make a message searchable by meaning · @sarunw on X
- Three decisions, one declaration · @sarunw on X
- indexingKey is a translation · @sarunw on X
- Siri can read what's on your screen in iOS 27 · @sarunw on X
- When one item fills the screen, annotate it with NSUserActivity · @sarunw on X
- In iOS 27, Siri uses Transferable too · @sarunw on X
- IntentValueQuery: match the incoming value, or create it · @sarunw on X
- Folded, iPhone Duo is an iPhone. Unfolded, it's an iPad · @sarunw on X
- Is .appEntityIdentifier + Transferable the intended way to let Siri send an on-screen image to another app? · Apple Developer Forums
Faites du pli une partie de votre app.
Nous présentons les apps et les jeux qui exploitent vraiment l’iPhone Duo. Envoyez-nous la vôtre avec un lien vers l’App Store, ou découvrez ce que d’autres ont créé.