App Intents in iOS 27: Hintergrund, Synchronisierung, Spotlight
App Intents kam mit iOS 16 als Apples typisierte, strukturierte API für Aktionen in Shortcuts, Siri und Spotlight; iOS 17 erweiterte das Framework um App-Intents-gestützte Widgets; iOS 18 machte es zum Vertrag für die Aktionsfläche von Apple Intelligence; iOS 26 brachte es in Visual Intelligence und interaktive Snippets. iOS 27 verändert den Zuschnitt dieser Wette erneut, und die Veränderung ist mechanisch statt kosmetisch: Ein Intent kann nun über das 30-Sekunden-Hintergrundlimit hinaus laufen, eine Entität kann eine Identität tragen, die die Reise über die Geräte eines Benutzers übersteht, und eine Abfrage kann ihren eigenen Spotlight-Index reparieren, wenn das System danach verlangt. iOS 27 fügt Leistungsfähigkeit hinzu, keine Verzierung.1
Jede vorherige Veröffentlichung erweiterte, wer Ihre Intents aufrufen konnte. iOS 27 erweitert, was Ihre Intents nach dem Aufruf tun können. Ein Synchronisierungs-Intent, der auf einige Tausend Datensätzen operiert, lieferte sich früher ein Wettrennen mit einem 30-Sekunden-Timer und verlor; nun bittet er das System um mehr Spielraum und meldet während der Arbeit seinen Fortschritt. Eine Entität, die auf dem iPhone das eine und auf dem Mac etwas anderes bedeutete, wird nun auf beiden zum selben Objekt aufgelöst. Dieser Beitrag geht die iOS-27-Oberfläche anhand von Apples Dokumentation durch, im selben Rahmen wie der Rest des Clusters: was eine App, die App Intents bereits ausliefert, ergänzt, um jede neue Fähigkeit zu gewinnen.
Kurzfassung
LongRunningIntenterweitert die Hintergrundlaufzeit eines Intents über das 30-Sekunden-Limit des Systems hinaus. Sie kapseln die Arbeit inperformBackgroundTask(options:operation:)und übergebenLongRunningTaskOptions; das Protokoll verfeinertProgressReportingIntent, weshalb die Fortschrittsmeldung eine Pflicht ist, keine Option. Live Activities stellt diesen Fortschritt automatisch dar.234SyncableEntityerklärt, dass eineAppEntityeinen über die Geräte eines Benutzers hinweg konsistenten Bezeichner trägt, womit das System auf iPhone, Mac und Watch auf dasselbe Objekt verweisen kann (Siri nutzt dies, um ein Gespräch von einem Gerät an ein anderes zu übergeben).5IndexedEntityQueryfügt einerEntityQueryUnterstützung für die Spotlight-Neuindizierung hinzu, sodass das System Ihre Abfrage bitten kann, die betroffenen Entitäten erneut zu spenden, wenn es ein Problem mit dem Index Ihrer App feststellt.6AppUnionValueundAppUnionValueCasesProviding(erzeugt durch das Makro@UnionValue) erlauben es einem einzelnen Parameter, mehrere verschiedene Entitätstypen mit ordentlicher Auswahl-UI und Parameterzusammenfassungen anzunehmen.78OwnershipProvidingEntity,EntityOwnershipundEntityCollectiondecken eigentümerbewusste Bestätigung und Effizienz bei Massenvorgängen ab;RunSystemShortcutIntentundIntentExecutionTargetsdecken durch Widgets ausgelöste Systemaktionen ab sowie die Frage, welcher Prozess einen Intent ausführt.910111213
Die 30-Sekunden-Wand: LongRunningIntent
Das Limit der Hintergrundausführung war die stille Decke dessen, was ein App Intent leisten konnte. Wenn das System einen Intent im Hintergrund ausführt (der Benutzer bittet Siri zu synchronisieren, sperrt dann das Telefon und steckt es ein), gewährte es ihm traditionell etwa 30 Sekunden zur Fertigstellung.2 Für das Protokollieren eines Glases Wasser ist das großzügig. Für die Synchronisierung einer Bibliothek, das Ausführen von Inferenz auf dem Gerät oder die Verarbeitung einer großen Datei sind 30 Sekunden eine Guillotine: Das System beendet die Aufgabe mitten im Schreibvorgang, und der Benutzer erhält ein halbfertiges Ergebnis.
iOS 27 führt LongRunningIntent ein, ein Protokoll, das ein Intent übernimmt, um das System um ein erweitertes Hintergrundfenster zu bitten.2 Apple nennt die Anwendungsfälle in der Dokumentation direkt: Dateioperationen, Datensynchronisierung, Inferenz von Machine-Learning-Modellen und die Verarbeitung von Daten über einen ausreichend großen Datensatz. Die Deklaration nennt Ihnen die wichtigste Einschränkung, bevor Sie eine Zeile schreiben:
protocol LongRunningIntent : ProgressReportingIntent
LongRunningIntent verfeinert ProgressReportingIntent.2 Sie können das Long-Running-Protokoll nicht übernehmen, ohne auch den Fortschritt zu melden — so ist es vorgesehen. Die erweiterte Laufzeit ist ein Privileg, das das System bedingt gewährt, und die Bedingung lautet, dass Sie ihm fortlaufend mitteilen, wie weit Sie gekommen sind. Hören Sie auf zu melden, kann das System die Erweiterung widerrufen und die Aufgabe vorzeitig beenden.3
Die Arbeit gehört in performBackgroundTask(options:operation:):
@discardableResult
func performBackgroundTask<T>(
options: LongRunningTaskOptions = [],
operation: @escaping () async throws -> T
) async throws -> T
Sie rufen die Methode aus dem perform()-Körper Ihres Intents auf und legen den aufwendigen Code in den operation-Closure. Die Methode erweitert Ihre Laufzeit auf Plattformen, die es vorgeben, automatisch über das standardmäßige 30-Sekunden-Limit hinaus; Sie starten keine separate Hintergrundaufgabe und verwalten keine UIBackgroundTaskIdentifier selbst.3 Ein Intent zur Bibliothekssynchronisierung sieht so aus:
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()
}
}
Zwei Dinge verdienen eine Erklärung, weil Tutorials sie überspringen.
Die Eigenschaft progress ist der Vertrag, keine Telemetrie. Apple ist eindeutig: Aktualisieren Sie, während Ihre Operation läuft, regelmäßig den Progress aus der ProgressReportingIntent-Konformität, und falls Sie das nicht tun, kann das System die Laufzeiterweiterung abbrechen und Ihre Aufgabe vorzeitig beenden.3 Fortschrittsmeldung bei einem normalen Intent ist eine nette Geste. Bei einem LongRunningIntent ist sie der Herzschlag, der die Erweiterung am Leben hält.
LongRunningTaskOptions deklariert Ressourcenanforderungen. Der Optionswert (eine Struktur im OptionSet-Stil, die standardmäßig [] ist) teilt dem System zusätzliche Ressourcenbedürfnisse für die Aufgabe mit, die es in die gewährte Laufzeit einrechnet.4 Eine leere Menge ist der Normalfall. Zu expliziten Optionen greifen Sie, wenn die Arbeit mehr als das Standardprofil benötigt.
Der Gewinn jenseits des Überlebens über die 30 Sekunden hinaus: Live Activities stellt den Fortschritt kostenlos dar. Die Dokumentation besagt, dass Live Activities den Fortschritt der Intent-Aufgabe anhand von Informationen anzeigt, die es automatisch von performBackgroundTask erhält, und Titel, Untertitel sowie einen Fortschrittsbalken aus den von Ihrem Code gemeldeten Werten zeichnet.3 Eine lange Synchronisierung, per Sprache gestartet, erscheint auf dem Sperrbildschirm als Live-Fortschrittsbalken, ohne dass Sie dafür auch nur eine einzige Live-Activity-Ansicht bauen. Der Intent meldet, das System stellt dar.
LongRunningIntent über das 30-Sekunden-Limit hinaus überlebt, mit einem Stopp-Button auf der Live Activity, sodass eine Person ihn jederzeit abbrechen kann.
In Sitzung 345 demonstriert Apple LongRunningIntent an einem echten Fehlerfall — einem Foto-Upload, der immer wieder innerhalb des 30-Sekunden-Fensters abstarb — und zeigt, wie das System den Lebenszyklus der Hintergrundaufgabe verwaltet, während es Fortschritt und ein Abbruch-Steuerelement als Live Activity anzeigt.14
Konsistente Identität: SyncableEntity
Eine AppEntity hat eine id. Auf einem einzelnen Gerät muss dieser Bezeichner nur innerhalb der App eindeutig sein. Die Schwierigkeiten beginnen in dem Moment, in dem ein Benutzer mehr als ein Gerät besitzt — was in Apples Ökosystem der Normalfall ist. Das „Projekt Atlas“, das der Benutzer mit Siri auf seinem iPhone besprochen hat, muss als erkennbar dasselbe „Projekt Atlas“ wiederzufinden sein, wenn er das Gespräch auf dem Mac wieder aufnimmt. Unterscheidet sich der lokale Bezeichner des iPhones von dem des Macs, hat das System zwei unverbundene Objekte und keine Möglichkeit, sie zu verknüpfen.
SyncableEntity ist die Antwort von iOS 27:5
protocol SyncableEntity : AppEntity
Es zu übernehmen erklärt, dass der Bezeichner Ihrer Entität geräteübergreifend identisch ist. Das Vorhandensein des Protokolls teilt dem System mit, dass es von einem Gerät zum anderen konsistent auf Ihre Entität verweisen kann. Apple nennt den konkreten Gewinn: Siri nutzt diese Fähigkeit, um ein Gespräch von einem Gerät an ein anderes zu übertragen.5
Der Aufwand für die Übernahme hängt vollständig davon ab, woher Ihre Bezeichner stammen. Wenn Ihre Entitäten bereits einen stabilen geräteübergreifenden Bezeichner verwenden (eine vom Server vergebene UUID, einen iCloud-Datensatznamen), übernehmen Sie SyncableEntity ohne weitere Änderungen, weil der Wert, den Sie bereits speichern, genau der Wert ist, den das System braucht.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
}
Die Falle ist die App, die auf jedem Gerät einen frischen lokalen Bezeichner erzeugt (eine automatisch hochgezählte Zeilen-ID, eine UUID pro Installation). Solche Bezeichner sind lokal eindeutig und geräteübergreifend bedeutungslos. Apples Empfehlung für diesen Fall: Übernehmen Sie das Protokoll und stützen Sie Ihre Identität auf den Wert, der tatsächlich stabil ist, damit das System einen dauerhaften Anker hat.5 Synchronisierung war das schwierige Problem, das Teams immer wieder von Hand mit eigener iCloud-Verrohrung lösten. SyncableEntity verlagert die Deklaration der geräteübergreifenden Identität ins Framework, wo Siri und der Rest des Systems darauf reagieren können.
Selbstheilende Suche: IndexedEntityQuery
iOS 16 erlaubte es Ihnen, IndexedEntity-Instanzen an Spotlight zu spenden, damit einzelne Entitäten durchsuchbar wurden. Die Lücke war die Reparatur. Indizes driften ab, werden beschädigt oder geraten nach einer Migration ins Hintertreffen, und bis iOS 27 war die einzige Abhilfe des Systems, sich auf das CSSearchableIndex-Delegate Ihrer App oder ihre CSImportExtension zu stützen.
IndexedEntityQuery schließt die Lücke, indem es dem System erlaubt, Ihre Abfrage um eine Neuindizierung zu bitten:6
protocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity
Die where-Klausel ist die Vorbedingung: Die Entität der Abfrage muss IndexedEntity entsprechen, weil eine Neuindizierung nur für Entitäten sinnvoll ist, die Sie überhaupt erst an Spotlight spenden.6 Wenn das System auf ein Problem mit dem Index einer App stößt, ruft es die Methoden dieses Protokolls auf, sofern Ihr Abfragetyp es übernimmt; tut Ihre Abfrage das nicht, bittet Spotlight stattdessen weiterhin Ihr CSSearchableIndex-Objekt (oder Ihre CSImportExtension, falls Sie durch Verknüpfung der Entität mit diesem Typ gespendet haben), die Arbeit zu erledigen.6 Sie implementieren die Methoden, um die angeforderten Entitäten abzurufen und sie über Ihren bevorzugten durchsuchbaren Index erneut zu spenden.
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)
}
}
Der Wert ist operativ. Eine App, die IndexedEntityQuery richtig umsetzt, nimmt an Spotlights Wiederherstellungsschleife teil: Das System bemerkt, dass der Index fehlerhaft ist, und die App liefert auf Anforderung frische Daten, anstatt dass der Benutzer bis zur nächsten vollständigen Neuspende stillschweigend Suchergebnisse verliert. Der grundlegende App-Intents-Beitrag des Clusters behandelte das bloße Bereitstellen von IndexedEntity, um Einträge durchsuchbar zu machen; IndexedEntityQuery ist die darauf aufsetzende Wartungsschicht.
Ein Parameter, mehrere Typen: AppUnionValue
Etliche reale Intents nehmen einen Parameter an, der legitimerweise einer von mehreren Typen ist. „Dieses teilen“, wobei „dieses“ ein Foto, ein Dokument oder ein Link ist. Die Behelfslösungen vor iOS 27 waren unschön: separate Intents pro Typ oder ein String-Diskriminator plus optionale Parameter, die die Auswahl-UI nicht sauber darstellen konnte.
iOS 27 fügt AppUnionValue für typisierte Union-Parameter hinzu:7
protocol AppUnionValue : TypeDisplayRepresentable
Ein Union-Wert, der dem Protokoll entspricht, funktioniert als Shortcuts-Parameter mit reichhaltigen Metadaten, sodass das System über die Mitgliedstypen hinweg eine passende Auswahl und eine sinnvolle Parameterzusammenfassung darstellen kann.7 Die Konformität schreiben Sie nicht von Hand. Das Makro @UnionValue erzeugt sie, und dasselbe Makro erzeugt ein verschachteltes Cases-Enum, das AppUnionValueCasesProviding entspricht:78
protocol AppUnionValueCasesProviding : AppEnum
AppUnionValueCasesProviding wird automatisch von dem Cases-Enum erfüllt, das das Makro ausgibt.8 Es überbrückt das Cases-Enum zurück zum Union-Wert-Typ und erbt Metadaten über seine AppEnum-Konformität, was jedem Fall seinen Anzeigenamen in der Auswahl verleiht.8 In der Praxis schreiben Sie die Union und annotieren sie:
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()
}
}
Das Makro @UnionValue kümmert sich um die Konformitäten AppUnionValue und AppUnionValueCasesProviding; wenn Sie über die Standardwerte hinaus eigene Metadaten möchten, implementieren Sie die Protokollanforderungen in einer Erweiterung.7 Ein Parameter, drei gültige Typen, eine Auswahl, die alle drei darzustellen weiß.
Eigentum und Effizienz
Zwei verschiedene iOS-27-Belange teilen sich diesen Abschnitt, weil beide das System davor schützen, unbedacht auf Ihren Daten zu handeln: eigentümerbewusste Bestätigung und Effizienz bei Massenvorgängen.
Destruktive Aktionen bestätigen: OwnershipProvidingEntity
Wenn Ihre App Entitäten an Intents übergibt und sie aus Ergebnissen zurückgibt, können Apple Intelligence, Siri und benutzerdefinierte Shortcuts app-übergreifend auf diesen Entitäten handeln. Für destruktive oder sensible Aktionen (das Löschen einer Entität, das Aktualisieren einer geteilten) wollen Sie eine Bestätigung, die den richtigen Kontext trägt. OwnershipProvidingEntity liefert ihn:9
protocol OwnershipProvidingEntity : AppEntity
Lassen Sie Ihre Entität dem entsprechen, und das System fragt mit passendem Kontext im Dialog nach einer Bestätigung, wenn ein Intent auf geteilten oder öffentlich zugänglichen Entitäten handelt.9 Der Eigentumszustand selbst ist ein EntityOwnership-Wert, eine flag-basierte Struktur, in der Sie einen einzelnen Zustand angeben oder mehrere mit einem OptionSet kombinieren: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
}
}
Der Mechanismus zählt am meisten für Apps mit geteilten Inhalten: Ein Fotoalbum, das Sie veröffentlicht oder mit der Familie geteilt haben, sollte eine vorsichtigere Bestätigung auslösen als ein privates, und OwnershipProvidingEntity ist die Art, wie die Entität dem System mitteilt, welches welches ist.9
Massenvorgänge ohne Speicherlast: EntityCollection
Das Auflösen von Entitäten ist nicht umsonst. Wenn ein Intent Hunderte von Entitäten als Parameter annimmt, kann es das System zu einem ungünstigen Zeitpunkt spürbar Zeit und Speicher kosten, jeden Bezeichner während der Parameterauflösung in eine vollständige Instanz aufzulösen. EntityCollection ist die Lösung:11
struct EntityCollection<Entity> where Entity : AppEntity
Die Sammlung speichert zunächst nur den Bezeichner jeder Entität und bietet eine Option, die vollständigen Instanzen später abzurufen, falls Sie sie brauchen.11 Verwenden Sie sie als Variablentyp, wenn Sie viele Bezeichner halten, und als Parametertyp, wenn ein Intent über eine große Menge operiert:
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()
}
}
Für einen Parameter, der Hunderte von Entitäten hält, spart das Überspringen der Auflösung pro Bezeichner genau dann Zeit und Speicher, wenn der Benutzer darauf wartet, dass die Aktion beginnt.11
Wo der Intent läuft: RunSystemShortcutIntent und IntentExecutionTargets
Zwei kleinere iOS-27-Ergänzungen runden die Oberfläche ab. RunSystemShortcutIntent ist ein ausschließlich für Widgets gedachter Intent zum Starten einer anderen App oder zum Ausführen eines App Shortcut, eines benutzerdefinierten Shortcuts oder einer Systemaktion über einen Widget-Button:12
struct RunSystemShortcutIntent
Sie verwenden ihn nur, um einen Button mit dem System-Shortcut-Initialisierer zu erzeugen und diesen Button in einem Widget zu platzieren; außerhalb dieses Kontexts tut er nichts Nützliches.12 Wenn der Benutzer das Widget konfiguriert, wählt er die Aktion des Buttons, und der Intent liefert die Metadaten, die das System für die Konfigurations-UI braucht. Er verschafft Ihrem Widget keinen Zugriff auf die Aktionen, Parameter oder die Implementierung eines Shortcuts. Wenn der gewählte Shortcut nach einer Eingabe fragen muss, kann das System die Kurzbefehle-App öffnen, um ihn auszuführen.12
IntentExecutionTargets beantwortet eine Frage, die auftaucht, sobald Sie Intents und Entitäten über Ihre App, Ihre Widget-Erweiterung und Ihre App-Intents-Erweiterung hinweg über ein Swift-Package oder Framework teilen: Welcher Prozess führt den Intent aus?13
struct IntentExecutionTargets
Standardmäßig führt das System einen Intent oder eine Entitätsabfrage über ein beliebiges verfügbares Ziel aus.13 Sie verwenden IntentExecutionTargets, um das einzuschränken. Apples Beispiel ist ein Browser: Das Hinzufügen eines Lesezeichens kann geschehen, während die App nicht sichtbar ist, sodass die App-Intents-Erweiterung in Ordnung geht; das Öffnen eines neuen Tabs ergibt aber nur Sinn, wenn die App sichtbar ist, was den eigenen Prozess der App erfordert.13 Sie deklarieren die gültigen Ziele, und das System hält die Einschränkung ein.
Adoptionspfad
Eine App, die App Intents bereits ausliefert, ergänzt die iOS-27-Fähigkeiten schrittweise; keine davon schreibt das Kernmodell um.
- Finden Sie Ihren langsamsten Intent. Jeder Intent, der Datei-I/O, Synchronisierung, Inferenz auf dem Gerät oder die Verarbeitung großer Datenmengen betreibt, ist ein Kandidat für
LongRunningIntent. Übernehmen Sie das Protokoll, verlagern Sie die Arbeit inperformBackgroundTask(options:operation:)und melden Sie durchgehendprogress. Sie erhalten eine Laufzeit jenseits der 30 Sekunden und kostenlosen Live-Activities-Fortschritt.23 - Prüfen Sie Ihre Entitätsbezeichner. Sind sie bereits geräteübergreifend stabil (Server-UUID, iCloud-Datensatzname), lassen Sie die betreffenden Entitäten
SyncableEntityentsprechen und liefern aus. Sind sie pro Gerät, beheben Sie zuerst die Identität, dann setzen Sie die Konformität um.5 - Fügen Sie
IndexedEntityQueryzu Abfragen hinzu, deren EntitätenIndexedEntitysind. Es ist rein additiv: Die Methoden werden nur aufgerufen, wenn das System eine Neuindizierung benötigt, und Ihre Suchergebnisse bleiben trotz Indexdrift korrekt.6 - Fassen Sie Mehrtyp-Parameter mit
@UnionValuezusammen. Überall, wo Sie eine Union mit separaten Intents oder einem Diskriminator-String vorgetäuscht haben, gibt Ihnen das Makro einen einzigen sauberen Parameter.7 - Markieren Sie geteilte Entitäten mit
OwnershipProvidingEntityund stellen Sie Parameter für große Mengen aufEntityCollectionum. Das Erste verbessert die Sicherheit der Bestätigung, das Zweite die Leistung der Auflösung.911
FAQ
Wie lange kann ein LongRunningIntent im Hintergrund laufen?
Apple dokumentiert die Untergrenze, die es anhebt, keine feste Obergrenze. Das System gibt einer Hintergrundaufgabe traditionell etwa 30 Sekunden zur Fertigstellung, und LongRunningIntent (über performBackgroundTask(options:operation:)) erweitert dieses Fenster auf Plattformen, die es vorgeben, automatisch über das Standardlimit hinaus.23 Die Erweiterung ist bedingt: Sie müssen den Progress aus der ProgressReportingIntent-Konformität fortlaufend aktualisieren, und wenn Sie aufhören, kann das System die Erweiterung abbrechen und Ihre Aufgabe vorzeitig beenden.3 Behandeln Sie die Fortschrittsmeldung als den Preis für die zusätzliche Laufzeit.
Muss ich Fortschritt melden, um LongRunningIntent zu nutzen?
Ja. LongRunningIntent ist als protocol LongRunningIntent : ProgressReportingIntent deklariert, weshalb seine Übernahme die ProgressReportingIntent-Konformität und ihren Progress erfordert.2 Über das Zufriedenstellen des Compilers hinaus halten regelmäßige Fortschrittsaktualisierungen die Hintergrundlaufzeiterweiterung am Leben und speisen den Titel, den Untertitel und den Fortschrittsbalken, die Live Activities automatisch aus performBackgroundTask darstellt.3
Was ändert SyncableEntity zur Laufzeit tatsächlich?
Es erklärt, dass der Bezeichner Ihrer Entität über die Geräte eines Benutzers hinweg identisch ist, womit das System das Objekt überall als eine Entität behandeln kann statt als separate Objekte pro Gerät.5 Die konkrete Fähigkeit, die Apple nennt: Siri kann ein Gespräch über diese Entität von einem Gerät an ein anderes übertragen. Sind Ihre Bezeichner bereits geräteübergreifend stabil, übernehmen Sie das Protokoll ohne weitere Änderungen; sind sie pro Gerät, verankern Sie die Identität zuerst neu auf einem stabilen Wert.5
Wann ruft das System IndexedEntityQuery auf?
Wenn es auf ein Problem mit dem Spotlight-Index Ihrer App stößt und Ihr Abfragetyp IndexedEntityQuery übernimmt (wobei seine Entität IndexedEntity entspricht).6 Das System ruft die Methoden des Protokolls auf, damit Sie die betroffenen Entitäten abrufen und sie erneut an Spotlight spenden. Übernimmt Ihre Abfrage das Protokoll nicht, greift Spotlight darauf zurück, Ihr CSSearchableIndex-Objekt zu bitten, oder Ihre CSImportExtension, falls Sie über diesen Typ gespendet haben.6
Warum EntityCollection statt eines einfachen Arrays von Entitäten verwenden?
EntityCollection<Entity> speichert vorab nur den Bezeichner jeder Entität und ruft die vollständigen Instanzen bei Bedarf später ab.11 Als Intent-Parameter hindert es das System daran, jeden Bezeichner während der Parameterauflösung in eine vollständige Instanz aufzulösen, was bei einem Parameter, der Hunderte von Entitäten hält, in einem potenziell kritischen Moment Zeit und Speicher spart.11 Ein einfaches [Entity]-Array löst alles eifrig auf.
Ist RunSystemShortcutIntent außerhalb von Widgets nutzbar?
Nein. Er existiert ausschließlich, um einen Button mit dem System-Shortcut-Initialisierer für die Platzierung in einem Widget zu erzeugen, und bietet in anderen Kontexten keine Funktionalität.12 Er liefert Metadaten für die Konfigurations-UI des Widgets und repräsentiert die vom Benutzer gewählte Aktion; er verschafft Ihrem Widget oder Ihrer App keinen Zugriff auf die Aktionen, Parameter oder die Implementierung des zugrunde liegenden Shortcuts.12
Der vollständige Apple-Ökosystem-Cluster: typisierte App Intents; die iOS-26-Ergänzungen; die Routing-Frage gegenüber MCP-Tools; Foundation Models; die neue Steuerung des Tool-Callings in Foundation Models; die Unterscheidung zwischen Laufzeit und Tooling LLM; drei Oberflächen; das Single-Source-of-Truth-Muster; MCP-Server neben einer App; Live Activities; die watchOS-Laufzeit; SwiftUI-Interna; SwiftData-Schemadisziplin; Liquid-Glass-Muster; Auslieferung über mehrere Plattformen; die Plattformmatrix; das Vision-Framework; @Observable-Interna; Barrierefreiheit als Plattform. Der Hub befindet sich bei der Apple-Ökosystem-Serie. Für den breiteren Kontext von iOS mit KI-Agenten siehe den Leitfaden zur iOS-Agentenentwicklung.
Quellenangaben
-
Apple Developer Documentation: App Intents. Die Framework-Referenz, die
AppIntent,AppEntity, Abfragen, Parameter und die iOS-27-Ergänzungen abdeckt. ↩ -
Apple Developer Documentation:
LongRunningIntent(iOS 27.0 beta). “An interface you use to extend the background execution time of an app intent that performs a long-running task.” Deklariert alsprotocol LongRunningIntent : ProgressReportingIntent; das System gibt Hintergrundaufgaben traditionell bis zu 30 Sekunden. ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
performBackgroundTask(options:operation:)(iOS 27.0 beta). Führt eine Operation im Hintergrund mit erweiterter Zeit über das standardmäßige 30-Sekunden-Limit hinaus aus; erfordert regelmäßige Fortschrittsaktualisierungen, sonst kann das System die Erweiterung abbrechen; Live Activities stellt den Fortschritt automatisch dar. ↩↩↩↩↩↩↩↩↩ -
Apple Developer Documentation:
LongRunningTaskOptions(iOS 27.0 beta). Optionen zum Konfigurieren von Long-Running-Aufgaben; deklariert zusätzliche Ressourcenanforderungen, übergeben anperformBackgroundTask(options:operation:). ↩↩ -
Apple Developer Documentation:
SyncableEntity(iOS 27.0 beta). “An interface that indicates your entity has an identifier that’s consistent across devices.” Deklariert alsprotocol SyncableEntity : AppEntity; Siri nutzt es, um ein Gespräch zwischen Geräten zu übertragen. ↩↩↩↩↩↩↩↩ -
Apple Developer Documentation:
IndexedEntityQuery(iOS 27.0 beta). “An interface that adds Spotlight reindexing support to your entity query.” Deklariert alsprotocol IndexedEntityQuery : EntityQuery where Self.Entity : IndexedEntity. ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
AppUnionValue(iOS 27.0 beta). “A protocol that provides nominal type identity and metadata for union values.” Deklariert alsprotocol AppUnionValue : TypeDisplayRepresentable; die Konformität wird durch das Makro@UnionValueerzeugt. ↩↩↩↩↩↩ -
Apple Developer Documentation:
AppUnionValueCasesProviding(iOS 27.0 beta). Deklariert alsprotocol AppUnionValueCasesProviding : AppEnum; wird automatisch von dem durch das Makro@UnionValueerzeugtenCases-Enum erfüllt. ↩↩↩↩ -
Apple Developer Documentation:
OwnershipProvidingEntity(iOS 27.0 beta). “A type that provides the system with ownership and sharing context for an app entity.” Deklariert alsprotocol OwnershipProvidingEntity : AppEntity; fragt bei geteilten oder öffentlich zugänglichen Entitäten nach einer Bestätigung. ↩↩↩↩↩ -
Apple Developer Documentation:
EntityOwnership(iOS 27.0 beta). “A type that represents the ownership and sharing characteristics of an app entity.” Deklariert alsstruct EntityOwnership; flag-basiert, kombinierbar mit einemOptionSet. ↩↩ -
Apple Developer Documentation:
EntityCollection(iOS 27.0 beta). “An array of entity identifiers that you use to improve the efficiency of operations involving large numbers of entities.” Deklariert alsstruct EntityCollection<Entity> where Entity : AppEntity; speichert zunächst Bezeichner und löst vollständige Instanzen verzögert auf. ↩↩↩↩↩↩↩ -
Apple Developer Documentation:
RunSystemShortcutIntent(iOS 27.0 beta). “An app intent you use in widgets to open another app or perform an App Shortcut, custom shortcut, or system action.” Deklariert alsstruct RunSystemShortcutIntent; nur nutzbar, um einen Widget-Buttonzu erzeugen. ↩↩↩↩↩↩ -
Apple Developer Documentation:
IntentExecutionTargets(iOS 27.0 beta). “A set of options that describes which process performs an intent or entity query.” Deklariert alsstruct IntentExecutionTargets; schränkt die Ausführung auf die App, die App-Intents-Erweiterung oder ein beliebiges verfügbares Ziel ein. ↩↩↩↩ -
Apple, WWDC26 Session 345, “Discover new capabilities in the App Intents framework.” developer.apple.com/videos/play/wwdc2026/345. Apple demonstriert
LongRunningIntentan einem Foto-Upload-Intent, der immer wieder innerhalb des 30-Sekunden-Limits scheiterte, wobei das Framework den Lebenszyklus der Hintergrundaufgabe verwaltet und Fortschritt samt Stopp-Steuerelement als Live Activity anzeigt. ↩