App Intents dans iOS 27 : exécution en arrière-plan, synchronisation, Spotlight
Les App Intents sont arrivés avec iOS 16 comme l’API typée d’Apple pour les actions structurées, au service de Shortcuts, de Siri et de Spotlight ; iOS 17 les a étendus aux widgets pilotés par App Intents ; iOS 18 en a fait le contrat de la surface d’action d’Apple Intelligence ; iOS 26 les a poussés dans Visual Intelligence et les extraits interactifs. iOS 27 redessine encore la forme du pari, et le changement est mécanique plutôt que cosmétique : un intent peut désormais s’exécuter au-delà de la limite de 30 secondes en arrière-plan, une entité peut porter une identité qui survit au passage d’un appareil à l’autre chez un même utilisateur, et une requête peut réparer son propre index Spotlight lorsque le système le lui demande. iOS 27 ajoute de la capacité, pas du sucre.1
Chaque version précédente élargissait qui pouvait appeler vos intents. iOS 27 élargit ce que vos intents peuvent faire une fois appelés. Un intent de synchronisation qui opérait sur quelques milliers d’enregistrements courait jadis contre un minuteur de 30 secondes et perdait la course ; il demande désormais davantage de marge au système et rend compte de sa progression pendant qu’il travaille. Une entité qui signifiait une chose sur iPhone et autre chose sur Mac se résout maintenant vers le même objet sur les deux. Cet article parcourt la surface d’iOS 27 à la lumière de la documentation Apple, avec le même cadre que le reste de la série : ce qu’une application qui expose déjà des App Intents doit ajouter pour gagner chaque nouvelle capacité.
En bref
LongRunningIntentprolonge la durée d’exécution en arrière-plan d’un intent au-delà de la limite système de 30 secondes. Vous enveloppez le travail dansperformBackgroundTask(options:operation:)et passezLongRunningTaskOptions; le protocole affineProgressReportingIntent, si bien que rendre compte de la progression est une obligation, pas une option. Les Live Activities affichent cette progression automatiquement.234SyncableEntitydéclare qu’uneAppEntityporte un identifiant cohérent sur l’ensemble des appareils d’un utilisateur, ce qui permet au système de désigner le même objet sur iPhone, Mac et Watch (Siri s’en sert pour transmettre une conversation d’un appareil à l’autre).5IndexedEntityQueryajoute la prise en charge de la réindexation Spotlight à uneEntityQuery: lorsque le système signale un problème avec l’index de votre application, il peut demander à votre requête de redonner les entités concernées.6AppUnionValueetAppUnionValueCasesProviding(générés par la macro@UnionValue) permettent à un même paramètre d’accepter plusieurs types d’entités distincts, avec une interface de sélection correcte et des résumés de paramètres.78OwnershipProvidingEntity,EntityOwnershipetEntityCollectioncouvrent la confirmation tenant compte de la propriété et l’efficacité des opérations en masse ;RunSystemShortcutIntentetIntentExecutionTargetscouvrent les actions système lancées depuis un widget et le choix du processus qui exécute un intent.910111213
Le mur des 30 secondes : LongRunningIntent
La limite d’exécution en arrière-plan a longtemps constitué le plafond silencieux de ce qu’un App Intent pouvait accomplir. Lorsque le système exécute un intent en arrière-plan (l’utilisateur demande à Siri de synchroniser, puis verrouille le téléphone et le glisse dans sa poche), il accorde traditionnellement une trentaine de secondes pour terminer.2 Pour consigner un verre d’eau, c’est généreux. Pour synchroniser une bibliothèque, exécuter de l’inférence sur l’appareil ou traiter un gros fichier, 30 secondes sont une guillotine : le système tue la tâche en pleine écriture et l’utilisateur récupère un résultat à moitié terminé.
iOS 27 introduit LongRunningIntent, un protocole qu’un intent adopte pour demander au système une fenêtre d’arrière-plan prolongée.2 Apple nomme directement les cas d’usage dans la documentation : opérations sur fichiers, synchronisation de données, inférence d’apprentissage automatique et traitement de données sur un jeu de données suffisamment volumineux. La déclaration vous indique la contrainte la plus importante avant même d’écrire une ligne :
protocol LongRunningIntent : ProgressReportingIntent
LongRunningIntent affine ProgressReportingIntent.2 Vous ne pouvez pas adopter le protocole de longue durée sans rendre compte de la progression, et c’est voulu. La durée d’exécution prolongée est un privilège que le système accorde sous condition, et la condition est que vous continuiez à lui dire où vous en êtes. Cessez de le faire et le système peut révoquer l’extension et mettre fin à la tâche prématurément.3
Le travail prend place à l’intérieur de performBackgroundTask(options:operation:) :
@discardableResult
func performBackgroundTask<T>(
options: LongRunningTaskOptions = [],
operation: @escaping () async throws -> T
) async throws -> T
Vous appelez la méthode depuis le corps perform() de votre intent et placez le code coûteux dans la closure operation. La méthode prolonge automatiquement votre durée d’exécution au-delà de la limite standard de 30 secondes sur les plateformes qui l’imposent ; vous ne démarrez pas de tâche d’arrière-plan distincte et ne gérez pas vous-même de UIBackgroundTaskIdentifier.3 Un intent de synchronisation de bibliothèque ressemble à ceci :
import AppIntents
struct SyncLibraryIntent: LongRunningIntent {
static var title: LocalizedStringResource = "Sync Library"
func perform() async throws -> some IntentResult {
try await performBackgroundTask(options: []) {
let records = try await server.fetchPendingRecords()
for (offset, record) in records.enumerated() {
try await store.apply(record)
progress.completedUnitCount = Int64(offset + 1)
progress.totalUnitCount = Int64(records.count)
}
return ()
}
return .result()
}
}
Deux points méritent une explication, parce que les tutoriels les escamotent.
La propriété progress est le contrat, pas de la télémétrie. Apple est explicite : pendant que votre opération s’exécute, mettez à jour régulièrement le Progress issu de la conformité à ProgressReportingIntent, faute de quoi le système peut annuler l’extension de durée d’exécution et mettre fin à votre tâche prématurément.3 Rendre compte de la progression sur un intent ordinaire est une coquetterie. Sur un LongRunningIntent, c’est le battement de cœur qui maintient l’extension en vie.
LongRunningTaskOptions déclare les besoins en ressources. La valeur d’options (une structure de style OptionSet dont la valeur par défaut est []) renseigne le système sur les besoins en ressources supplémentaires de la tâche, qu’il prend en compte dans la durée d’exécution qu’il accorde.4 Un ensemble vide est le cas courant. Vous recourez à des options explicites lorsque le travail exige davantage que le profil par défaut.
Le gain, au-delà de survivre au-delà des 30 secondes : les Live Activities affichent la progression gratuitement. La documentation précise que les Live Activities affichent la progression de la tâche de l’intent à partir des informations qu’elles reçoivent automatiquement de performBackgroundTask, dessinant le titre, le sous-titre et une barre de progression à partir des valeurs que votre code rapporte.3 Une longue synchronisation lancée à la voix apparaît sur l’écran verrouillé sous la forme d’une barre de progression en direct, sans que vous ayez construit la moindre vue Live Activity pour elle. L’intent rapporte, le système affiche.
LongRunningIntent, avec un bouton d’arrêt sur la Live Activity pour qu’une personne puisse l’annuler à tout moment.
Dans la session 345, Apple met LongRunningIntent à l’épreuve d’un cas d’échec réel, un téléversement de photos qui mourait sans cesse dans la fenêtre des 30 secondes, et montre le système gérant le cycle de vie de la tâche d’arrière-plan tout en faisant remonter la progression et une commande d’annulation sous forme de Live Activity.14
Une identité cohérente : SyncableEntity
Une AppEntity possède un id. Sur un seul appareil, cet identifiant n’a qu’à être unique au sein de l’application. Les ennuis commencent dès que l’utilisateur possède plus d’un appareil, ce qui, dans l’écosystème Apple, est la norme. Le « Projet Atlas » dont l’utilisateur a parlé à Siri sur son iPhone doit être reconnaissable comme le même « Projet Atlas » lorsqu’il reprend la conversation sur le Mac. Si l’identifiant local de l’iPhone diffère de celui du Mac, le système a deux objets sans rapport et aucun moyen de les relier.
SyncableEntity est la réponse d’iOS 27 :5
protocol SyncableEntity : AppEntity
L’adopter déclare que l’identifiant de votre entité est identique sur tous les appareils. La présence du protocole indique au système qu’il peut désigner votre entité de façon cohérente d’un appareil à l’autre. Apple en donne le bénéfice concret : Siri se sert de cette capacité pour transférer une conversation d’un appareil à un autre.5
Le coût d’adoption dépend entièrement de l’origine de vos identifiants. Si vos entités utilisent déjà un identifiant stable entre appareils (un UUID émis par un serveur, un nom d’enregistrement iCloud), vous adoptez SyncableEntity sans autre modification, car la valeur que vous stockez déjà est celle dont le système a besoin.5
import AppIntents
struct ProjectEntity: SyncableEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Project"
static var defaultQuery = ProjectQuery()
// A UUID issued by the backend and identical on every device.
var id: UUID
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
@Property(title: "Name") var name: String
}
Le piège, c’est l’application qui forge un identifiant local neuf sur chaque appareil (un identifiant de ligne auto-incrémenté, un UUID par installation). Ces identifiants sont uniques localement et dénués de sens d’un appareil à l’autre. La recommandation d’Apple dans ce cas : adoptez le protocole et ancrez votre identité sur la valeur réellement stable, afin que le système dispose d’un point d’ancrage durable.5 La synchronisation était le problème difficile que les équipes résolvaient sans cesse à la main, avec leur propre plomberie iCloud. SyncableEntity déplace la déclaration d’identité multi-appareils dans le framework, là où Siri et le reste du système peuvent l’exploiter.
Une recherche qui se répare elle-même : IndexedEntityQuery
iOS 16 vous permettait de donner des instances IndexedEntity à Spotlight pour rendre les entités individuelles recherchables. La lacune, c’était la réparation. Les index dérivent, se corrompent ou prennent du retard après une migration, et jusqu’à iOS 27 le seul recours du système était de s’appuyer sur le délégué CSSearchableIndex de votre application ou sur son CSImportExtension.
IndexedEntityQuery comble la lacune en laissant le système demander à votre requête de réindexer :6
protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity
La clause where est la condition préalable : l’entité de la requête doit se conformer à IndexedEntity, car la réindexation n’a de sens que pour les entités que vous donnez à Spotlight en premier lieu.6 Lorsque le système rencontre un problème avec l’index d’une application, il appelle les méthodes de ce protocole si votre type de requête l’adopte ; sinon, Spotlight continue de demander à votre objet CSSearchableIndex (ou à votre CSImportExtension, si vous avez donné l’entité en l’associant à ce type) de faire le travail à la place.6 Vous implémentez les méthodes pour récupérer les entités demandées et les redonner via l’index de recherche de votre choix.
import AppIntents
import CoreSpotlight
struct PhotoQuery: IndexedEntityQuery {
func entities(for identifiers: [Photo.ID]) async throws -> [Photo] {
try await library.photos(matching: identifiers)
}
func suggestedEntities() async throws -> [Photo] {
try await library.recentPhotos(limit: 20)
}
// Called by the system during reindexing. Fetch the requested
// entities and donate them again to Spotlight.
func entities(matching string: String) async throws -> [Photo] {
try await library.photos(matchingText: string)
}
}
La valeur est opérationnelle. Une application qui maîtrise IndexedEntityQuery participe à la boucle de récupération de Spotlight : le système constate que l’index est erroné et l’application fournit des données fraîches à la demande, au lieu que l’utilisateur perde discrètement des résultats de recherche jusqu’à la prochaine redonation complète. L’article fondateur sur les App Intents de la série couvrait l’exposition d’un IndexedEntity nu pour rendre les entrées recherchables ; IndexedEntityQuery est la couche de maintenance posée par-dessus.
Un paramètre, plusieurs types : AppUnionValue
Bien des intents réels acceptent un paramètre qui est légitimement de l’un parmi plusieurs types. « Partager ceci » où « ceci » est une photo, un document ou un lien. Les solutions de contournement antérieures à iOS 27 étaient laides : un intent distinct par type, ou un discriminant sous forme de chaîne assorti de paramètres optionnels que l’interface de sélection ne pouvait pas afficher proprement.
iOS 27 ajoute AppUnionValue pour les paramètres d’union typés :7
protocol AppUnionValue : TypeDisplayRepresentable
Une valeur d’union conforme au protocole fonctionne comme un paramètre Shortcuts doté de métadonnées riches, ce qui permet au système de présenter un sélecteur approprié et un résumé de paramètre sensé à travers les types membres.7 Vous n’écrivez pas la conformité à la main. La macro @UnionValue la génère, et la même macro génère une énumération Cases imbriquée qui se conforme à AppUnionValueCasesProviding :78
protocol AppUnionValueCasesProviding : AppEnum
AppUnionValueCasesProviding est conformé automatiquement par l’énumération Cases que la macro émet.8 Elle fait le pont entre l’énumération des cas et le type de valeur d’union, et hérite des métadonnées via sa conformité à AppEnum, ce qui donne à chaque cas son nom d’affichage dans le sélecteur.8 En pratique, vous écrivez l’union et vous l’annotez :
import AppIntents
@UnionValue
enum ShareTarget {
case photo(PhotoEntity)
case document(DocumentEntity)
case link(URL)
}
struct ShareIntent: AppIntent {
static var title: LocalizedStringResource = "Share Item"
@Parameter(title: "Item")
var target: ShareTarget
func perform() async throws -> some IntentResult {
// Switch over the concrete case and act accordingly.
return .result()
}
}
La macro @UnionValue prend en charge les conformités à AppUnionValue et AppUnionValueCasesProviding ; si vous voulez des métadonnées personnalisées au-delà des valeurs par défaut, vous implémentez les exigences du protocole dans une extension.7 Un paramètre, trois types valides, un sélecteur qui sait afficher les trois.
Propriété et efficacité
Deux préoccupations distinctes d’iOS 27 partagent cette section parce que toutes deux protègent le système d’une action négligente sur vos données : la confirmation tenant compte de la propriété, et l’efficacité des opérations en masse.
Confirmer les actions destructrices : OwnershipProvidingEntity
Lorsque votre application passe des entités dans les intents et les renvoie depuis les résultats, Apple Intelligence, Siri et les raccourcis personnalisés peuvent agir sur ces entités d’une application à l’autre. Pour les actions destructrices ou sensibles (supprimer une entité, en mettre à jour une partagée), vous voulez une confirmation qui porte le bon contexte. OwnershipProvidingEntity le fournit :9
protocol OwnershipProvidingEntity : AppEntity
Conformez votre entité à ce protocole et le système demande une confirmation, avec le contexte approprié dans la boîte de dialogue, lorsqu’un intent agit sur des entités partagées ou accessibles publiquement.9 L’état de propriété lui-même est une valeur EntityOwnership, une structure à base de drapeaux où vous spécifiez un état unique ou en combinez plusieurs avec un OptionSet :10
import AppIntents
struct AlbumEntity: OwnershipProvidingEntity {
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Album"
static var defaultQuery = AlbumQuery()
var id: UUID
var isSharedWithFamily: Bool
var isPublished: Bool
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
@Property(title: "Name") var name: String
// Reflect how the user has shared this album so the system can
// calibrate its confirmation dialog.
var ownership: EntityOwnership {
var state: EntityOwnership = []
if isSharedWithFamily || isPublished {
state = .shared
}
return state
}
}
Le mécanisme compte avant tout pour les applications à contenu partagé : un album photo que vous avez publié ou partagé en famille devrait produire une confirmation plus prudente qu’un album privé, et OwnershipProvidingEntity est la façon dont l’entité indique au système lequel est lequel.9
Le traitement en masse sans surcoût mémoire : EntityCollection
Résoudre des entités n’est pas gratuit. Lorsqu’un intent accepte des centaines d’entités en paramètre, forcer le système à résoudre chaque identifiant en une instance complète pendant la résolution des paramètres peut coûter un temps et une mémoire non négligeables à un mauvais moment. EntityCollection est le correctif :11
struct EntityCollection<Entity> where Entity : AppEntity
La collection ne stocke d’abord que l’identifiant de chaque entité et offre la possibilité de récupérer les instances complètes plus tard, si vous en avez besoin.11 Utilisez-la comme type de variable lorsque vous détenez beaucoup d’identifiants, et comme type de paramètre lorsqu’un intent opère sur un grand ensemble :
import AppIntents
struct DisableNotificationsIntent: AppIntent {
static var title: LocalizedStringResource = "Disable Notifications"
// Hundreds of conversations resolve lazily, not all at once.
@Parameter(title: "Conversations")
var conversations: EntityCollection<ConversationEntity>
func perform() async throws -> some IntentResult {
return .result()
}
}
Pour un paramètre contenant des centaines d’entités, éviter la résolution identifiant par identifiant économise du temps et de la mémoire précisément au moment où l’utilisateur attend que l’action démarre.11
Où l’intent s’exécute : RunSystemShortcutIntent et IntentExecutionTargets
Deux ajouts plus modestes d’iOS 27 complètent la surface. RunSystemShortcutIntent est un intent réservé aux widgets, destiné à lancer une autre application ou à exécuter un App Shortcut, un raccourci personnalisé ou une action système depuis un bouton de widget :12
struct RunSystemShortcutIntent
Vous ne l’utilisez que pour initialiser un Button avec l’initialiseur de raccourci système et placer ce bouton dans un widget ; il ne sert à rien d’utile en dehors de ce contexte.12 Lorsque l’utilisateur configure le widget, il choisit l’action du bouton, et l’intent fournit les métadonnées dont le système a besoin pour l’interface de configuration. Il ne donne pas à votre widget accès aux actions, aux paramètres ou à l’implémentation d’un raccourci. Si le raccourci choisi a besoin de demander une saisie, le système peut ouvrir l’application Raccourcis pour l’exécuter.12
IntentExecutionTargets répond à une question qui surgit dès que vous partagez intents et entités entre votre application, votre extension de widget et votre extension App Intents via un package ou un framework Swift : quel processus exécute l’intent ?13
struct IntentExecutionTargets
Par défaut, le système exécute un intent ou une requête d’entité en utilisant n’importe quelle cible disponible.13 Vous utilisez IntentExecutionTargets pour restreindre cela. L’exemple d’Apple est un navigateur : l’ajout d’un signet peut se faire alors que l’application n’est pas visible, l’extension App Intents convient donc, mais l’ouverture d’un nouvel onglet n’a de sens que lorsque l’application est visible, ce qui exige le propre processus de l’application.13 Vous déclarez les cibles valides et le système respecte la contrainte.
Trajectoire d’adoption
Une application qui expose déjà des App Intents ajoute les capacités d’iOS 27 de façon incrémentale ; aucune ne réécrit le modèle de base.
- Repérez votre intent le plus lent. Tout intent qui fait des E/S sur fichiers, de la synchronisation, de l’inférence sur l’appareil ou du traitement de grands volumes de données est un candidat à
LongRunningIntent. Adoptez le protocole, déplacez le travail dansperformBackgroundTask(options:operation:)et rendez compte deprogresstout du long. Vous obtenez une durée d’exécution au-delà de 30 secondes et la progression Live Activities gratuitement.23 - Auditez les identifiants de vos entités. S’ils sont déjà stables entre appareils (UUID serveur, nom d’enregistrement iCloud), conformez les entités concernées à
SyncableEntityet livrez. S’ils sont propres à chaque appareil, corrigez d’abord l’identité, puis conformez.5 - Ajoutez
IndexedEntityQueryaux requêtes dont les entités sont desIndexedEntity. C’est purement additif : les méthodes ne sont appelées que lorsque le système a besoin d’une réindexation, et vos résultats de recherche restent corrects malgré la dérive de l’index.6 - Regroupez les paramètres multi-types avec
@UnionValue. Partout où vous simuliez une union avec des intents séparés ou une chaîne de discrimination, la macro vous donne un paramètre net et unique.7 - Marquez les entités partagées avec
OwnershipProvidingEntityet basculez les paramètres à grand ensemble versEntityCollection. Le premier améliore la sûreté des confirmations, le second améliore les performances de résolution.911
FAQ
Combien de temps un LongRunningIntent peut-il s’exécuter en arrière-plan ?
Apple documente le plancher qu’il relève, pas un plafond fixe. Le système accorde traditionnellement à une tâche d’arrière-plan une trentaine de secondes pour terminer, et LongRunningIntent (via performBackgroundTask(options:operation:)) prolonge automatiquement cette fenêtre au-delà de la limite standard sur les plateformes qui l’imposent.23 L’extension est conditionnelle : vous devez continuer à mettre à jour le Progress issu de la conformité à ProgressReportingIntent, et si vous arrêtez, le système peut annuler l’extension et mettre fin à votre tâche prématurément.3 Considérez le compte rendu de progression comme le prix de la durée d’exécution supplémentaire.
Suis-je obligé de rendre compte de la progression pour utiliser LongRunningIntent ?
Oui. LongRunningIntent est déclaré comme protocol LongRunningIntent : ProgressReportingIntent, si bien que l’adopter impose la conformité à ProgressReportingIntent et son Progress.2 Au-delà de satisfaire le compilateur, des mises à jour régulières de la progression maintiennent en vie l’extension de durée d’exécution en arrière-plan et alimentent le titre, le sous-titre et la barre de progression que les Live Activities affichent automatiquement à partir de performBackgroundTask.3
Que change réellement SyncableEntity à l’exécution ?
Il déclare que l’identifiant de votre entité est identique sur l’ensemble des appareils d’un utilisateur, ce qui permet au système de traiter l’objet comme une seule entité partout, au lieu d’objets distincts par appareil.5 La capacité concrète que nomme Apple : Siri peut transférer une conversation portant sur cette entité d’un appareil à l’autre. Si vos identifiants sont déjà stables entre appareils, vous adoptez le protocole sans autre modification ; s’ils sont propres à chaque appareil, vous réancrez d’abord l’identité sur une valeur stable.5
Quand le système appelle-t-il IndexedEntityQuery ?
Lorsqu’il rencontre un problème avec l’index Spotlight de votre application et que votre type de requête adopte IndexedEntityQuery (avec son entité conforme à IndexedEntity).6 Le système appelle les méthodes du protocole pour vous faire récupérer les entités concernées et les redonner à Spotlight. Si votre requête n’adopte pas le protocole, Spotlight se rabat sur votre objet CSSearchableIndex, ou sur votre CSImportExtension si vous avez donné via ce type.6
Pourquoi utiliser EntityCollection plutôt qu’un simple tableau d’entités ?
EntityCollection<Entity> ne stocke d’emblée que l’identifiant de chaque entité et ne récupère les instances complètes que plus tard, en cas de besoin.11 En tant que paramètre d’intent, il empêche le système de forcer la résolution de chaque identifiant en instance complète pendant la résolution des paramètres, ce qui, pour un paramètre contenant des centaines d’entités, économise du temps et de la mémoire à un moment potentiellement critique.11 Un simple tableau [Entity] résout tout de manière hâtive.
RunSystemShortcutIntent est-il utilisable en dehors des widgets ?
Non. Il existe uniquement pour initialiser un Button avec l’initialiseur de raccourci système en vue d’un placement dans un widget, et il n’offre aucune fonctionnalité dans d’autres contextes.12 Il fait remonter les métadonnées pour l’interface de configuration du widget et représente l’action choisie par l’utilisateur ; il ne donne pas à votre widget ou à votre application accès aux actions, aux paramètres ou à l’implémentation du raccourci sous-jacent.12
La série complète sur l’écosystème Apple : les App Intents typés ; les ajouts d’iOS 26 ; la question du routage face aux outils MCP ; Foundation Models ; le nouveau contrôle de l’appel d’outils dans Foundation Models ; la distinction LLM entre environnement d’exécution et outillage ; les trois surfaces ; le motif de source unique de vérité ; les serveurs MCP aux côtés d’une application ; les Live Activities ; l’environnement d’exécution watchOS ; les rouages internes de SwiftUI ; la discipline de schéma SwiftData ; les motifs Liquid Glass ; la livraison multiplateforme ; la matrice des plateformes ; le framework Vision ; les rouages internes de @Observable ; l’accessibilité comme plateforme. Le hub se trouve à la série sur l’écosystème Apple. Pour un contexte plus large sur iOS avec des agents IA, consultez le guide de développement d’agents iOS.
Références
-
Documentation pour les développeurs Apple : App Intents. La référence du framework couvrant
AppIntent,AppEntity, les requêtes, les paramètres et les ajouts d’iOS 27. ↩ -
Documentation pour les développeurs Apple :
LongRunningIntent(iOS 27.0 beta). « Une interface que vous utilisez pour prolonger le temps d’exécution en arrière-plan d’un app intent qui effectue une tâche de longue durée. » Déclaré commeprotocol LongRunningIntent : ProgressReportingIntent; le système accorde traditionnellement aux tâches d’arrière-plan jusqu’à 30 secondes. ↩↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
performBackgroundTask(options:operation:)(iOS 27.0 beta). Exécute une opération en arrière-plan avec un temps prolongé au-delà de la limite standard de 30 secondes ; exige des mises à jour régulières de la progression, faute de quoi le système peut annuler l’extension ; les Live Activities affichent la progression automatiquement. ↩↩↩↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
LongRunningTaskOptions(iOS 27.0 beta). Options de configuration des tâches de longue durée ; déclare des besoins en ressources supplémentaires, passés àperformBackgroundTask(options:operation:). ↩↩ -
Documentation pour les développeurs Apple :
SyncableEntity(iOS 27.0 beta). « Une interface qui indique que votre entité possède un identifiant cohérent sur tous les appareils. » Déclaré commeprotocol SyncableEntity : AppEntity; Siri s’en sert pour transférer une conversation entre appareils. ↩↩↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
IndexedEntityQuery(iOS 27.0 beta). « Une interface qui ajoute la prise en charge de la réindexation Spotlight à votre requête d’entité. » Déclaré commeprotocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity. ↩↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
AppUnionValue(iOS 27.0 beta). « Un protocole qui fournit une identité de type nominale et des métadonnées pour les valeurs d’union. » Déclaré commeprotocol AppUnionValue : TypeDisplayRepresentable; la conformité est générée par la macro@UnionValue. ↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
AppUnionValueCasesProviding(iOS 27.0 beta). Déclaré commeprotocol AppUnionValueCasesProviding : AppEnum; conformé automatiquement par l’énumérationCasesgénérée par la macro@UnionValue. ↩↩↩↩ -
Documentation pour les développeurs Apple :
OwnershipProvidingEntity(iOS 27.0 beta). « Un type qui fournit au système le contexte de propriété et de partage d’une app entity. » Déclaré commeprotocol OwnershipProvidingEntity : AppEntity; demande une confirmation sur les entités partagées ou accessibles publiquement. ↩↩↩↩↩ -
Documentation pour les développeurs Apple :
EntityOwnership(iOS 27.0 beta). « Un type qui représente les caractéristiques de propriété et de partage d’une app entity. » Déclaré commestruct EntityOwnership; à base de drapeaux, combinable avec unOptionSet. ↩↩ -
Documentation pour les développeurs Apple :
EntityCollection(iOS 27.0 beta). « Un tableau d’identifiants d’entités que vous utilisez pour améliorer l’efficacité des opérations impliquant un grand nombre d’entités. » Déclaré commestruct EntityCollection<Entity> where Entity : AppEntity; stocke d’abord les identifiants et résout les instances complètes de manière paresseuse. ↩↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
RunSystemShortcutIntent(iOS 27.0 beta). « Un app intent que vous utilisez dans les widgets pour ouvrir une autre application ou effectuer un App Shortcut, un raccourci personnalisé ou une action système. » Déclaré commestruct RunSystemShortcutIntent; utilisable uniquement pour initialiser unButtonde widget. ↩↩↩↩↩↩ -
Documentation pour les développeurs Apple :
IntentExecutionTargets(iOS 27.0 beta). « Un ensemble d’options qui décrit quel processus exécute un intent ou une requête d’entité. » Déclaré commestruct IntentExecutionTargets; restreint l’exécution à l’application, à l’extension App Intents ou à n’importe quelle cible disponible. ↩↩↩↩ -
Apple, session 345 de la WWDC26, « Discover new capabilities in the App Intents framework ». developer.apple.com/videos/play/wwdc2026/345. Apple montre
LongRunningIntentrésolvant un intent de téléversement de photos qui échouait sans cesse dans la limite des 30 secondes, le framework gérant le cycle de vie de la tâche d’arrière-plan et faisant remonter la progression ainsi qu’une commande d’arrêt sous forme de Live Activity. ↩