App Intents 2.0 und Siri Shortcuts: iOS 27 Automatisierungs-Guide

Vollständiger Leitfaden zu App Intents 2.0 und Siri Shortcuts für iOS 27. Streaming-Antworten, Mehrschritt-Konversationen, View Annotations und Foundation Models Integration.

App Intents und Siri Shortcuts für fortgeschrittene iOS-Automatisierung mit Swift und Apple Intelligence

App Intents 2.0 und Siri Shortcuts stellen den einzigen Weg für Drittanbieter-Apps dar, um mit Siri unter iOS 27 zu interagieren. Nach der WWDC 2026 hat Apple SiriKit abgekündigt und App Intents als obligatorisches Framework für Sprachinteraktion, Spotlight-Entdeckung und Automatisierungs-Workflows positioniert.

Was dieser Artikel behandelt

Dieser Artikel zeigt die vollständige Erstellung von App Intents und Siri Shortcuts für iOS 27, von den Grundlagen über Streaming-Antworten, Mehrschritt-Konversationen und die View Annotations API.

Das App-Intents-2.0-Framework verstehen

Das mit iOS 16 eingeführte und auf der WWDC 2026 auf Version 2.0 erweiterte App-Intents-Framework ist ein Swift-natives, deklaratives Framework zur Erstellung systemweit auffindbarer Aktionen. iOS 27 bringt vier wesentliche Neuerungen: Streaming-Antworten für langandauernde Operationen, Mehrschritt-Konversationen, View Annotations zur Referenzierung von Bildschirmelementen und App Schemas für semantisches Verständnis ohne Trainingsphrasen.

Auf der WWDC 2026 hat Apple SiriKit offiziell abgekündigt und App Intents zum ausschließlichen Weg gemacht, über den Siri mit Drittanbieter-Apps interagieren kann. Bestehender SiriKit-Code kompiliert weiterhin mit Deprecation-Warnungen, aber Apple hat ein Zeitfenster von zwei bis drei Jahren bis zur Entfernung signalisiert.

TaskIntent.swiftswift
import AppIntents

// An AppIntent represents an action users can perform
struct CreateTaskIntent: AppIntent {
    // Title displayed in Shortcuts and Siri
    static var title: LocalizedStringResource = "Create a task"

    // Description for accessibility and suggestions
    static var description = IntentDescription(
        "Creates a new task in the application."
    )

    // Parameter with automatic validation
    @Parameter(title: "Task title")
    var taskTitle: String

    // Optional parameter with default value
    @Parameter(title: "Priority", default: .medium)
    var priority: TaskPriority

    // Action execution with async/await
    func perform() async throws -> some IntentResult & ReturnsValue<TaskEntity> {
        // Create task via service
        let task = TaskService.shared.createTask(
            title: taskTitle,
            priority: priority
        )

        // Return created entity for chaining
        return .result(value: TaskEntity(task: task))
    }
}

Der Intent deklariert seine Parameter über den Property Wrapper @Parameter, sodass Siri fehlende Werte im Gespräch abfragen kann. Die Methode perform() führt die Geschäftslogik aus und liefert ein typisiertes Ergebnis. Das Typsystem selbst dient als Schema, das Siri AI dynamisch erkennt.

Streaming-Antworten für langandauernde Aktionen

App Intents 2.0 führt Streaming-Antworten ein, die es Intents ermöglichen, während der Ausführung Fortschritt zu melden, anstatt bis zum Abschluss zu blockieren. Diese Fähigkeit adressiert Szenarien wie Datei-Uploads, Datensynchronisation oder komplexe Berechnungen, bei denen Nutzer Feedback benötigen.

StreamingExportIntent.swiftswift
import AppIntents

struct ExportDataIntent: AppIntent {
    static var title: LocalizedStringResource = "Export data"

    @Parameter(title: "Format")
    var format: ExportFormat

    // Streaming response for progress reporting
    func perform() async throws -> some IntentResult & ProvidesDialog {
        let totalItems = DataService.shared.itemCount
        var processed = 0

        // Stream progress updates to Siri
        for item in DataService.shared.allItems {
            await exportItem(item, format: format)
            processed += 1

            // Report progress at intervals
            if processed % 100 == 0 {
                await reportProgress(
                    "Exported (processed) of (totalItems) items..."
                )
            }
        }

        return .result(
            dialog: "Export complete. (totalItems) items saved as (format.rawValue)."
        )
    }
}

Streaming-Antworten ermöglichen natürliches Feedback bei Operationen, die länger als wenige Sekunden dauern, und halten den Nutzer engagiert, anstatt ihn in Stille warten zu lassen.

Mehrschritt-Konversationen

Mehrschritt-Konversationen ermöglichen Siri, klärende Fragen zu stellen und die Interaktion innerhalb einer Sitzung fortzuführen. Diese Funktion transformiert App Intents von Einmal-Befehlen zu konversationellen Workflows.

ConversationalTaskIntent.swiftswift
import AppIntents

struct SmartTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Create smart task"

    @Parameter(title: "Task title")
    var taskTitle: String?

    @Parameter(title: "Priority")
    var priority: TaskPriority?

    @Parameter(title: "Due date")
    var dueDate: Date?

    // Multi-turn conversation flow
    func perform() async throws -> some IntentResult & ProvidesDialog {
        // Request missing parameters conversationally
        let title = try await taskTitle ?? requestValue(
            for: .,
            dialog: "What should the task be called?"
        )

        let taskPriority = try await priority ?? requestValue(
            for: .,
            dialog: "What priority level?"
        )

        // Optional follow-up
        let date: Date?
        if try await requestConfirmation(
            result: .result(dialog: "Should this task have a due date?")
        ) {
            date = try await requestValue(
                for: .,
                dialog: "When is it due?"
            )
        } else {
            date = nil
        }

        let task = TaskService.shared.createTask(
            title: title,
            priority: taskPriority,
            dueDate: date
        )

        return .result(
            dialog: "Created '(task.title)' with (taskPriority.rawValue) priority."
        )
    }
}

Die Methode requestValue(for:dialog:) pausiert die Ausführung bis Siri die Antwort des Nutzers erhält und ermöglicht so einen natürlichen Hin-und-Her-Austausch anstatt alle Parameter vorab zu erfordern.

View Annotations API für Bildschirmreferenzen

Die View Annotations API, neu in iOS 27, ermöglicht es Nutzern, UI-Elemente direkt in Siri-Befehlen zu referenzieren mit Phrasen wie "dieses Foto", "das dritte" oder "diese Nachricht". Diese Fähigkeit erfordert die Annotation von SwiftUI-Views mit semantischen Informationen.

AnnotatedPhotoView.swiftswift
import SwiftUI
import AppIntents

struct PhotoGridView: View {
    let photos: [Photo]

    var body: some View {
        LazyVGrid(columns: [GridItem(.adaptive(minimum: 100))]) {
            ForEach(photos) { photo in
                PhotoThumbnail(photo: photo)
                    // Annotate view for Siri reference
                    .appIntentAnnotation(
                        entity: PhotoEntity(photo: photo),
                        label: photo.title
                    )
            }
        }
    }
}

// Intent that accepts view-referenced entities
struct SharePhotoIntent: AppIntent {
    static var title: LocalizedStringResource = "Share photo"

    // Parameter resolved from on-screen annotation
    @Parameter(title: "Photo", supportsViewAnnotation: true)
    var photo: PhotoEntity

    func perform() async throws -> some IntentResult & ProvidesDialog {
        await ShareService.share(photo.id)
        return .result(dialog: "Photo shared.")
    }
}

Wenn ein Nutzer "teile dieses Foto" sagt, während er das Grid betrachtet, löst Siri "dieses" auf die aktuell fokussierte oder zuletzt angetippte PhotoEntity über die Annotation auf. Das eliminiert die Reibung, Objekte verbal beschreiben zu müssen.

Gerätekompatibilität

View Annotations erfordern iOS 27, aber die App-Intents-Schicht selbst funktioniert auf jedem iOS-27-Gerät einschließlich iPhone 11 und neuer. Apple-Intelligence-Funktionen wie Bildschirmbewusstsein benötigen iPhone 15 Pro oder neuer.

App Entities für Daten definieren

App Entities repräsentieren die "Substantive" der App: die Objekte, auf denen Intents operieren. Sie ermöglichen Siri das Verstehen, Suchen und Manipulieren von App-Daten. Effektive Entities zu erstellen ist essenziell für SwiftUI State Management Patterns in Intent-gesteuerten Apps.

TaskEntity.swiftswift
import AppIntents

// Internal data model
struct Task: Identifiable, Codable {
    let id: UUID
    var title: String
    var priority: TaskPriority
    var isCompleted: Bool
    var dueDate: Date?
}

// Entity exposed to the system
struct TaskEntity: AppEntity {
    // Required unique identifier
    var id: UUID

    // Displayable properties
    var title: String
    var priority: TaskPriority
    var isCompleted: Bool

    // Display configuration in the system
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Task"

    // Visual representation of the instance
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "(title)",
            subtitle: "(priority.rawValue)",
            image: .init(systemName: isCompleted ? "checkmark.circle.fill" : "circle")
        )
    }

    // Default query for searching entities
    static var defaultQuery = TaskEntityQuery()

    // Initializer from internal model
    init(task: Task) {
        self.id = task.id
        self.title = task.title
        self.priority = task.priority
        self.isCompleted = task.isCompleted
    }
}

// Optimized entity query with search
struct TaskEntityQuery: EntityStringQuery {
    // Text search with service-side filtering
    func entities(matching string: String) async throws -> [TaskEntity] {
        TaskService.shared.search(query: string, limit: 10)
            .map { TaskEntity(task: /bin/bash) }
    }

    // Search by identifiers
    func entities(for identifiers: [UUID]) async throws -> [TaskEntity] {
        TaskService.shared.fetchTasks()
            .filter { identifiers.contains(/bin/bash.id) }
            .map { TaskEntity(task: /bin/bash) }
    }

    // Limited suggestions for performance
    func suggestedEntities() async throws -> [TaskEntity] {
        TaskService.shared.fetchRecentTasks(limit: 5)
            .map { TaskEntity(task: /bin/bash) }
    }
}

Das EntityStringQuery-Protokoll fügt Textsuche hinzu und ermöglicht Siri, Entities nach Namen zu finden. Die Methode suggestedEntities() versorgt Siri und die Kurzbefehle-Oberfläche mit relevanten Optionen.

AppEnum für feste Werte verwenden

Verwende AppEnum für Typen mit einer festen Wertemenge (Priorität, Status) und AppEntity für dynamische, vom Nutzer erstellte Typen (Aufgaben, Notizen, Kontakte). Das Vermischen verursacht unnötige Komplexität.

App Enums für feste Werte erstellen

App Enums exponieren aufgezählte Typen an das System und ermöglichen Siri kontextbezogene Auswahlmöglichkeiten mit visuellen Darstellungen.

TaskPriority.swiftswift
import AppIntents

// Enum exposed to the system
enum TaskPriority: String, AppEnum, Codable {
    case low
    case medium
    case high

    // Type name displayed
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Priority"

    // Representation of each case
    static var caseDisplayRepresentations: [TaskPriority: DisplayRepresentation] = [
        .low: DisplayRepresentation(
            title: "Low",
            image: .init(systemName: "arrow.down.circle")
        ),
        .medium: DisplayRepresentation(
            title: "Medium",
            image: .init(systemName: "minus.circle")
        ),
        .high: DisplayRepresentation(
            title: "High",
            image: .init(systemName: "exclamationmark.circle")
        )
    ]
}

SF-Symbols-Icons bereichern die Anzeige in Kurzbefehlen und Siri-Vorschlägen und machen die Auswahl schneller als verbale Beschreibungen.

Bereit für deine iOS-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

AppShortcutsProvider implementieren

Der AppShortcutsProvider exponiert App Shortcuts an das System und macht sie ohne Nutzerkonfiguration sofort verfügbar. Diese Shortcuts erscheinen in Spotlight, Siri, am Action Button und in den neuen agentischen Siri-AI-Workflows.

ShortcutsProvider.swiftswift
import AppIntents

// Provider declaring all app shortcuts
struct TaskAppShortcutsProvider: AppShortcutsProvider {
    // Maximum 10 shortcuts per application
    @AppShortcutsBuilder
    static var appShortcuts: [AppShortcut] {
        // Shortcut to create a task
        AppShortcut(
            intent: CreateTaskIntent(),
            phrases: [
                // The .applicationName placeholder is REQUIRED
                "Create a task with (.applicationName)",
                "New task in (.applicationName)",
                "Add a task to (.applicationName)"
            ],
            shortTitle: "Create Task",
            systemImageName: "plus.circle"
        )

        // Shortcut with dynamic parameter
        AppShortcut(
            intent: CompleteTaskIntent(),
            phrases: [
                "Complete (.) in (.applicationName)",
                "Mark (.) as done with (.applicationName)"
            ],
            shortTitle: "Complete Task",
            systemImageName: "checkmark.circle"
        )

        // Shortcut for smart conversational intent
        AppShortcut(
            intent: SmartTaskIntent(),
            phrases: [
                "Quick task (.applicationName)",
                "Remind me (.applicationName)"
            ],
            shortTitle: "Smart Task",
            systemImageName: "brain"
        )
    }
}

Sprachphrasen müssen den Platzhalter (.applicationName) enthalten, damit Siri die Ziel-App identifiziert. Dynamische Parameter wie (.) ermöglichen kontextbezogene Befehle.

Intents in interaktiven Widgets

App Intents integrieren sich mit WidgetKit, um interaktive Widgets zu erstellen. Das Verständnis von SwiftUI Navigation Patterns hilft beim Aufbau von Widget-zu-App-Übergängen.

TaskWidgetIntents.swiftswift
import AppIntents
import WidgetKit

// Widget-optimized intent (fast execution)
struct ToggleTaskFromWidgetIntent: AppIntent {
    static var title: LocalizedStringResource = "Toggle task"

    @Parameter(title: "Task ID")
    var taskID: String

    init() {}

    init(taskID: UUID) {
        self.taskID = taskID.uuidString
    }

    // No dialog for widgets
    func perform() async throws -> some IntentResult {
        guard let uuid = UUID(uuidString: taskID) else {
            return .result()
        }

        TaskService.shared.toggleCompletion(taskId: uuid)

        // Immediate widget refresh
        WidgetCenter.shared.reloadTimelines(ofKind: "TaskWidget")

        return .result()
    }
}

// Widget view with interactive button
import SwiftUI

struct TaskWidgetView: View {
    let task: Task

    var body: some View {
        Button(intent: ToggleTaskFromWidgetIntent(taskID: task.id)) {
            HStack {
                Image(systemName: task.isCompleted ? "checkmark.circle.fill" : "circle")
                    .foregroundStyle(task.isCompleted ? .green : .secondary)

                Text(task.title)
                    .strikethrough(task.isCompleted)
            }
            .padding()
        }
        .buttonStyle(.plain)
    }
}

Widgets nutzen die Syntax Button(intent:), um die Interaktion direkt mit dem App Intent zu verbinden, ohne die App zu öffnen.

Foundation Models Framework Integration

iOS 27 führt das Foundation Models Framework ein, das On-Device-LLM-Inferenz ermöglicht. Während Foundation Models keine direkte Siri-Integration hat, können Apps es innerhalb von App Intents nutzen, um natürliche Sprache zu verarbeiten oder Antworten zu generieren.

AIAssistedIntent.swiftswift
import AppIntents
import FoundationModels

struct SummarizeNotesIntent: AppIntent {
    static var title: LocalizedStringResource = "Summarize notes"

    @Parameter(title: "Topic")
    var topic: String

    func perform() async throws -> some IntentResult & ProvidesDialog {
        let notes = NoteService.shared.fetchNotes(matching: topic)
        let content = notes.map(.content).joined(separator: "

")

        // Use Foundation Models for on-device summarization
        let model = LanguageModel.default
        let summary = try await model.generate(
            prompt: "Summarize these notes in 2 sentences: (content)",
            maxTokens: 100
        )

        return .result(dialog: IntentDialog(summary))
    }
}

Foundation Models läuft mit etwa 30 Token pro Sekunde on-device ohne Kosten pro Anfrage. Das Framework erfordert iPhone 15 Pro oder iPhone 16 und neuer für On-Device-Verarbeitung.

Migration von SiriKit zu App Intents

Für Apps, die noch SiriKit verwenden, folgt die Migration einem strukturierten Prozess. Xcode 27 bietet ein "Convert to App Intent"-Tool für Widget-Konfigurationen, aber benutzerdefinierte Handler erfordern manuelles Umschreiben.

swift
// Before: SiriKit Intent Handler
class CreateTaskIntentHandler: NSObject, CreateTaskIntentHandling {
    func handle(intent: CreateTaskIntent) async -> CreateTaskIntentResponse {
        guard let title = intent.taskTitle else {
            return CreateTaskIntentResponse(code: .failure, userActivity: nil)
        }

        let task = TaskService.shared.createTask(title: title)
        return CreateTaskIntentResponse.success(task: task)
    }
}

// After: App Intent (iOS 27)
struct CreateTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Create a task"

    @Parameter(title: "Task title")
    var taskTitle: String

    func perform() async throws -> some IntentResult & ReturnsValue<TaskEntity> {
        let task = TaskService.shared.createTask(title: taskTitle)
        return .result(value: TaskEntity(task: task))
    }
}

Die Migration eliminiert .intentdefinition-Dateien und Intent Extension Targets. Die gesamte Intent-Logik wandert als Swift-Structs in das Haupt-App-Target.

App Intents testen

Das AppIntentsTesting-Framework validiert Intents über die tatsächliche Siri-, Kurzbefehle- und Spotlight-Infrastruktur ohne Mocks.

TaskIntentTests.swiftswift
import XCTest
import AppIntentsTesting
@testable import TaskApp

final class TaskIntentTests: XCTestCase {

    override func setUp() {
        super.setUp()
        TaskService.shared.reset()
    }

    func testCreateTaskIntent() async throws {
        // Given
        var intent = CreateTaskIntent()
        intent.taskTitle = "Test Task"
        intent.priority = .high

        // When
        let result = try await intent.perform()

        // Then
        let tasks = TaskService.shared.fetchTasks()
        XCTAssertEqual(tasks.count, 1)
        XCTAssertEqual(tasks.first?.title, "Test Task")
        XCTAssertEqual(tasks.first?.priority, .high)
    }

    func testEntityQuery() async throws {
        // Given
        let task1 = TaskService.shared.createTask(title: "Task 1", priority: .low)
        let task2 = TaskService.shared.createTask(title: "Task 2", priority: .high)

        let query = TaskEntityQuery()

        // When
        let entities = try await query.entities(for: [task1.id, task2.id])

        // Then
        XCTAssertEqual(entities.count, 2)
    }

    func testStreamingIntent() async throws {
        // Given
        var intent = ExportDataIntent()
        intent.format = .json

        // When
        let result = try await intent.perform()

        // Then: verify completion dialog
        XCTAssertNotNil(result)
    }
}

Tests prüfen das Intent-Verhalten unabhängig von der Systemoberfläche und erkennen Regressionen vor dem Deployment.

Sources

App Intents iOS 27 Implementierungs-Checkliste

Für Apps, die iOS 27 anvisieren, sind App Intents nicht mehr optional. Siri AI komponiert mehrstufige Aktionen über Apps hinweg, und Apps ohne veröffentlichte Intents werden von diesen agentischen Workflows ausgeschlossen.

  • AppIntents für die Hauptaktionen der App erstellen
  • AppEntities für manipulierbare Daten definieren
  • AppEnum für aufgezählte Typen verwenden
  • AppShortcutsProvider mit Sprachphrasen implementieren
  • Maximales Limit von 10 App Shortcuts einhalten
  • (.applicationName) in allen Phrasen einbinden
  • View Annotations zu SwiftUI-Views für Bildschirmreferenzen hinzufügen
  • Streaming-Antworten für langandauernde Operationen implementieren
  • Mehrschritt-Konversationen für komplexe Workflows unterstützen
  • Von SiriKit migrieren bevor das Deprecation-Fenster schließt
  • Intents mit dem AppIntentsTesting-Framework testen
  • Titel und Beschreibungen lokalisieren

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Tägliche Challenge

Findest du den Bug in iOS?

Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Anthony Fillion-Maillet

Geschrieben von

Anthony Fillion-Maillet

Gründer von SharpSkill

Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.

Aktualisiert am 20. August 2026

Tags

#app-intents
#siri-shortcuts
#ios
#swift
#apple-intelligence

Teilen

Verwandte Artikel