App Intents i Siri Shortcuts: zaawansowana automatyzacja iOS 2026

Kompletny przewodnik po App Intents i Siri Shortcuts dla iOS 18+. Tworzenie własnych akcji Siri, integracja Apple Intelligence i automatyzacja aplikacji Swift w 2026.

App Intents i Siri Shortcuts dla zaawansowanej automatyzacji iOS ze Swift i Apple Intelligence

W 2026 roku, dzięki Apple Intelligence i frameworkowi App Intents, aplikacje iOS wkraczają w erę, w której intencja użytkownika jest ważniejsza niż interfejs graficzny. Aplikacje, które nie udostępniają intentów, stają się niewidoczne w systemie zorientowanym na AI. App Intents stanowi fundament umożliwiający Siri, Spotlight, widgetom i Action Button interakcję z funkcjonalnościami aplikacji.

Co obejmuje ten artykuł

Ten artykuł przedstawia kompletne tworzenie App Intents i Siri Shortcuts dla iOS 18+, od fundamentalnych koncepcji po integrację z Apple Intelligence i App Intent Domains.

Zrozumienie frameworku App Intents

Framework App Intents, wprowadzony wraz z iOS 16, modernizuje konstrukcję intentów w Swift, zastępując starszy framework SiriKit Intents. Ta deklaratywna architektura pozwala tworzyć akcje wykrywalne przez system: Spotlight, aplikacja Skróty, Siri i Action Button.

TaskIntent.swiftswift
import AppIntents

// AppIntent reprezentuje akcję, którą użytkownik może wykonać
struct CreateTaskIntent: AppIntent {
    // Tytuł wyświetlany w Skrótach i Siri
    static var title: LocalizedStringResource = "Utwórz zadanie"

    // Opis dla dostępności i sugestii
    static var description = IntentDescription(
        "Tworzy nowe zadanie w aplikacji."
    )

    // Parametr z automatyczną walidacją
    @Parameter(title: "Tytuł zadania")
    var taskTitle: String

    // Parametr opcjonalny z wartością domyślną
    @Parameter(title: "Priorytet", default: .medium)
    var priority: TaskPriority

    // Wykonanie akcji
    func perform() async throws -> some IntentResult & ReturnsValue<TaskEntity> {
        // Utworzenie zadania przez serwis
        let task = TaskService.shared.createTask(
            title: taskTitle,
            priority: priority
        )

        // Zwraca utworzoną encję do łańcuchowania
        return .result(value: TaskEntity(task: task))
    }
}

Intent deklaruje swoje parametry przez property wrapper @Parameter, pozwalając Siri pytać o brakujące wartości. Metoda perform() wykonuje logikę biznesową i zwraca wynik o określonym typie.

Definiowanie App Entities dla danych

App Entities reprezentują "rzeczowniki" aplikacji: obiekty, na których operują intenty. Pozwalają Siri rozumieć i manipulować danymi aplikacji.

TaskEntity.swiftswift
import AppIntents

// Wewnętrzny model danych
struct Task: Identifiable, Codable {
    let id: UUID
    var title: String
    var priority: TaskPriority
    var isCompleted: Bool
    var dueDate: Date?
}

// Encja wystawiona systemowi
struct TaskEntity: AppEntity {
    // Wymagany unikalny identyfikator
    var id: UUID

    // Wyświetlane właściwości
    var title: String
    var priority: TaskPriority
    var isCompleted: Bool

    // Konfiguracja wyświetlania w systemie
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Zadanie"

    // Wizualna reprezentacja instancji
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "\(title)",
            subtitle: "\(priority.rawValue)",
            image: .init(systemName: isCompleted ? "checkmark.circle.fill" : "circle")
        )
    }

    // Domyślne zapytanie do wyszukiwania encji
    static var defaultQuery = TaskEntityQuery()

    // Initializer z modelu wewnętrznego
    init(task: Task) {
        self.id = task.id
        self.title = task.title
        self.priority = task.priority
        self.isCompleted = task.isCompleted
    }
}

// Zapytanie do wyszukiwania i filtrowania encji
struct TaskEntityQuery: EntityQuery {
    // Wyszukiwanie po identyfikatorach
    func entities(for identifiers: [UUID]) async throws -> [TaskEntity] {
        TaskService.shared.fetchTasks()
            .filter { identifiers.contains($0.id) }
            .map { TaskEntity(task: $0) }
    }

    // Sugestie wyświetlane w interfejsie
    func suggestedEntities() async throws -> [TaskEntity] {
        TaskService.shared.fetchTasks()
            .filter { !$0.isCompleted }
            .prefix(5)
            .map { TaskEntity(task: $0) }
    }
}

EntityQuery definiuje sposób, w jaki system wyszukuje i sugeruje encje. Metody entities(for:) i suggestedEntities() zasilają interfejsy Siri i Skrótów.

App Enums vs App Entities

Należy używać AppEnum dla typów ze stałym zbiorem wartości (priorytet, status), a AppEntity dla typów dynamicznych tworzonych przez użytkownika (zadania, notatki, kontakty).

Tworzenie App Enums dla stałych wartości

App Enums udostępniają systemowi typy wyliczeniowe, pozwalając Siri oferować kontekstowe wybory.

TaskPriority.swiftswift
import AppIntents

// Enum udostępniony systemowi
enum TaskPriority: String, AppEnum, Codable {
    case low
    case medium
    case high

    // Wyświetlana nazwa typu
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Priorytet"

    // Reprezentacja każdego przypadku
    static var caseDisplayRepresentations: [TaskPriority: DisplayRepresentation] = [
        .low: DisplayRepresentation(
            title: "Niski",
            image: .init(systemName: "arrow.down.circle")
        ),
        .medium: DisplayRepresentation(
            title: "Średni",
            image: .init(systemName: "minus.circle")
        ),
        .high: DisplayRepresentation(
            title: "Wysoki",
            image: .init(systemName: "exclamationmark.circle")
        )
    ]
}

// Enum dla statusu zadania
enum TaskStatus: String, AppEnum, Codable {
    case pending
    case inProgress
    case completed

    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Status"

    static var caseDisplayRepresentations: [TaskStatus: DisplayRepresentation] = [
        .pending: "Oczekujące",
        .inProgress: "W toku",
        .completed: "Ukończone"
    ]
}

Reprezentacje wizualne (ikony SF Symbols) wzbogacają wyświetlanie w Skrótach i sugestiach Siri.

Implementacja AppShortcutsProvider

AppShortcutsProvider udostępnia App Shortcuts systemowi, czyniąc je natychmiast dostępnymi bez konfiguracji użytkownika. Te skróty pojawiają się w Spotlight, Siri i Action Button.

ShortcutsProvider.swiftswift
import AppIntents

// Provider deklarujący wszystkie skróty aplikacji
struct TaskAppShortcutsProvider: AppShortcutsProvider {
    // Maksymalnie 10 skrótów na aplikację
    @AppShortcutsBuilder
    static var appShortcuts: [AppShortcut] {
        // Skrót do tworzenia zadania
        AppShortcut(
            intent: CreateTaskIntent(),
            phrases: [
                // Placeholder .applicationName jest WYMAGANY
                "Utwórz zadanie w \(.applicationName)",
                "Nowe zadanie w \(.applicationName)",
                "Dodaj zadanie do \(.applicationName)"
            ],
            shortTitle: "Utwórz zadanie",
            systemImageName: "plus.circle"
        )

        // Skrót do listowania zadań
        AppShortcut(
            intent: ListTasksIntent(),
            phrases: [
                "Pokaż moje zadania w \(.applicationName)",
                "Wyświetl zadania z \(.applicationName)",
                "Jakie są moje zadania \(.applicationName)"
            ],
            shortTitle: "Moje zadania",
            systemImageName: "list.bullet"
        )

        // Skrót z dynamicznym parametrem
        AppShortcut(
            intent: CompleteTaskIntent(),
            phrases: [
                "Ukończ \(\.$taskName) w \(.applicationName)",
                "Oznacz \(\.$taskName) jako wykonane w \(.applicationName)"
            ],
            shortTitle: "Ukończ zadanie",
            systemImageName: "checkmark.circle"
        )
    }
}

Frazy głosowe muszą zawierać placeholder \(.applicationName), aby Siri zidentyfikowała aplikację docelową. Dynamiczne parametry takie jak \(\.$taskName) umożliwiają komendy kontekstowe.

Limit 10 skrótów

Aplikacja może zadeklarować maksymalnie 10 App Shortcuts. Warto priorytetyzować akcje najczęstsze i najbardziej użyteczne dla użytkowników.

Intenty z parametrami złożonymi

Intenty mogą przyjmować złożone parametry, w tym encje i opcje konfiguracyjne.

CompleteTaskIntent.swiftswift
import AppIntents

struct CompleteTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Ukończ zadanie"

    static var description = IntentDescription(
        "Oznacza zadanie jako ukończone."
    )

    // Parametr typu encja z automatycznym wyszukiwaniem
    @Parameter(title: "Zadanie")
    var task: TaskEntity

    // Parametr opcjonalny z datą
    @Parameter(title: "Data ukończenia")
    var completionDate: Date?

    // Konfiguracja dialogu Siri
    static var parameterSummary: some ParameterSummary {
        Summary("Ukończ \(\.$task)") {
            \.$completionDate
        }
    }

    func perform() async throws -> some IntentResult & ProvidesDialog {
        // Aktualizacja zadania
        TaskService.shared.completeTask(
            id: task.id,
            completionDate: completionDate ?? Date()
        )

        // Feedback głosowy dla Siri
        return .result(
            dialog: "Zadanie \(task.title) zostało oznaczone jako ukończone."
        )
    }
}

// Intent zwracający listę encji
struct ListTasksIntent: AppIntent {
    static var title: LocalizedStringResource = "Wylistuj zadania"

    // Filtr opcjonalny
    @Parameter(title: "Status", default: nil)
    var statusFilter: TaskStatus?

    @Parameter(title: "Priorytet", default: nil)
    var priorityFilter: TaskPriority?

    func perform() async throws -> some IntentResult & ReturnsValue<[TaskEntity]> {
        var tasks = TaskService.shared.fetchTasks()

        // Zastosuj filtry
        if let status = statusFilter {
            tasks = tasks.filter {
                switch status {
                case .completed: return $0.isCompleted
                case .pending, .inProgress: return !$0.isCompleted
                }
            }
        }

        if let priority = priorityFilter {
            tasks = tasks.filter { $0.priority == priority }
        }

        let entities = tasks.map { TaskEntity(task: $0) }
        return .result(value: entities)
    }
}

ParameterSummary definiuje sposób, w jaki Siri prezentuje intent podczas wykonywania głosowego, dostarczając naturalnego feedbacku.

Gotowy na rozmowy o iOS?

Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.

Integracja z Apple Intelligence

iOS 18 wprowadza App Intent Domains, kolekcje API zaprojektowane dla konkretnych funkcjonalności. Te domeny pozwalają Apple Intelligence rozumieć i wykonywać akcje z większą precyzją.

BookmarkDomainIntents.swiftswift
import AppIntents

// Zgodność z domeną Bookmarks dla integracji Apple Intelligence
struct SaveBookmarkIntent: AppIntent {
    static var title: LocalizedStringResource = "Zapisz zakładkę"

    // Parametr URL z automatyczną walidacją
    @Parameter(title: "URL")
    var url: URL

    @Parameter(title: "Tytuł", default: nil)
    var title: String?

    @Parameter(title: "Folder", default: nil)
    var folder: BookmarkFolderEntity?

    // Otwórz aplikację w razie potrzeby
    static var openAppWhenRun: Bool = false

    func perform() async throws -> some IntentResult & ProvidesDialog {
        let bookmark = BookmarkService.shared.save(
            url: url,
            title: title,
            folder: folder?.id
        )

        return .result(
            dialog: "Zakładka zapisana: \(bookmark.title)"
        )
    }
}

// Intent ze świadomością zawartości ekranu (iOS 18.4+)
struct AnalyzeScreenContentIntent: AppIntent {
    static var title: LocalizedStringResource = "Analizuj zawartość"

    // Dostęp do kontekstu ekranu przez Apple Intelligence
    @Parameter(title: "Kontekst")
    var screenContext: String?

    func perform() async throws -> some IntentResult & ProvidesDialog {
        guard let context = screenContext else {
            return .result(dialog: "Brak zawartości do analizy.")
        }

        // Przetwarzaj zawartość wyekstrahowaną przez Apple Intelligence
        let analysis = ContentAnalyzer.analyze(context)

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

Predefiniowane domeny (Books, Camera, Spreadsheets) pozwalają Siri precyzyjnie odpowiadać na żądania dzięki modelom trenowanym na tych konkretnych zadaniach.

Akcje Siri z potwierdzeniem użytkownika

Dla wrażliwych akcji system może żądać potwierdzenia przed wykonaniem.

DeleteTaskIntent.swiftswift
import AppIntents

struct DeleteTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Usuń zadanie"

    @Parameter(title: "Zadanie")
    var task: TaskEntity

    // Wymaga potwierdzenia użytkownika
    static var isDiscoverable: Bool = true

    func perform() async throws -> some IntentResult & ProvidesDialog {
        // Żądanie potwierdzenia przez dialog
        try await requestConfirmation(
            result: .result(
                dialog: "Czy na pewno chcesz usunąć \(task.title)?"
            )
        )

        // Usuń po potwierdzeniu
        TaskService.shared.deleteTask(id: task.id)

        return .result(
            dialog: "Zadanie \(task.title) zostało usunięte."
        )
    }
}

// Intent z wieloma krokami dialogu
struct ScheduleTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Zaplanuj zadanie"

    @Parameter(title: "Zadanie")
    var task: TaskEntity

    @Parameter(title: "Data")
    var scheduledDate: Date

    @Parameter(title: "Przypomnienie", default: true)
    var setReminder: Bool

    static var parameterSummary: some ParameterSummary {
        When(\.$setReminder, .equalTo, true) {
            Summary("Zaplanuj \(\.$task) na \(\.$scheduledDate) z przypomnieniem")
        } otherwise: {
            Summary("Zaplanuj \(\.$task) na \(\.$scheduledDate)")
        }
    }

    func perform() async throws -> some IntentResult & ProvidesDialog {
        TaskService.shared.schedule(
            taskId: task.id,
            date: scheduledDate,
            reminder: setReminder
        )

        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .short

        let formattedDate = dateFormatter.string(from: scheduledDate)

        return .result(
            dialog: "Zadanie zaplanowane na \(formattedDate)."
        )
    }
}

Metoda requestConfirmation wstrzymuje wykonanie do walidacji użytkownika, chroniąc przed przypadkowymi akcjami.

Intenty w widgetach interaktywnych

App Intents naturalnie integrują się z WidgetKit do tworzenia interaktywnych widgetów w iOS 17+.

TaskWidgetIntents.swiftswift
import AppIntents
import WidgetKit

// Intent zoptymalizowany pod widget (szybkie wykonanie)
struct ToggleTaskFromWidgetIntent: AppIntent {
    static var title: LocalizedStringResource = "Przełącz zadanie"

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

    init() {}

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

    // Brak dialogu dla widgetów
    func perform() async throws -> some IntentResult {
        guard let uuid = UUID(uuidString: taskID) else {
            return .result()
        }

        TaskService.shared.toggleCompletion(taskId: uuid)

        // Natychmiastowe odświeżenie widgetu
        WidgetCenter.shared.reloadTimelines(ofKind: "TaskWidget")

        return .result()
    }
}

// Widok widgetu z interaktywnym przyciskiem
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)
    }
}

Widgety używają składni Button(intent:), aby bezpośrednio połączyć interakcję z App Intent, bez otwierania aplikacji.

Konfiguracja Action Button

Action Button w iPhone 15 Pro i nowszych może wyzwalać App Shortcuts bezpośrednio.

ActionButtonIntent.swiftswift
import AppIntents

// Intent zoptymalizowany pod Action Button
struct QuickCaptureIntent: AppIntent {
    static var title: LocalizedStringResource = "Szybkie przechwycenie"

    static var description = IntentDescription(
        "Szybko tworzy zadanie z tytułem."
    )

    // Otwiera aplikację do wprowadzenia
    static var openAppWhenRun: Bool = true

    func perform() async throws -> some IntentResult & OpensIntent {
        // Powiadomienie do otwarcia ekranu szybkiego przechwytywania
        NotificationCenter.default.post(
            name: .quickCaptureTriggered,
            object: nil
        )

        return .result(opensIntent: ShowQuickCaptureViewIntent())
    }
}

// Zadeklaruj w AppShortcutsProvider dla Action Button
extension TaskAppShortcutsProvider {
    @AppShortcutsBuilder
    static var appShortcuts: [AppShortcut] {
        // ... inne skróty

        AppShortcut(
            intent: QuickCaptureIntent(),
            phrases: [
                "Szybkie przechwycenie \(.applicationName)",
                "Szybka notatka \(.applicationName)"
            ],
            shortTitle: "Przechwyć",
            systemImageName: "bolt.circle"
        )
    }
}

Użytkownicy mogą skonfigurować Action Button do wyzwalania tego skrótu przez Ustawienia > Action Button.

Makra iOS 18+

iOS 18 wprowadza makra @DeferredProperty i @ComputedProperty redukujące boilerplate. App Intents mogą również znajdować się w Swift Packages dla wieloplatformowego ponownego użycia.

Intenty w Swift Packages

App Intents mogą być definiowane w Swift Packages do współdzielenia między iOS, macOS i watchOS.

Package.swiftswift
// swift-tools-version: 5.9
import PackageDescription

let package = Package(
    name: "TaskIntents",
    platforms: [
        .iOS(.v17),
        .macOS(.v14),
        .watchOS(.v10)
    ],
    products: [
        .library(name: "TaskIntents", targets: ["TaskIntents"])
    ],
    dependencies: [],
    targets: [
        .target(
            name: "TaskIntents",
            dependencies: []
        )
    ]
)

// Sources/TaskIntents/SharedIntents.swift
import AppIntents

// Wspólny intent wieloplatformowy
public struct SharedCreateTaskIntent: AppIntent {
    public static var title: LocalizedStringResource = "Utwórz zadanie"

    @Parameter(title: "Tytuł")
    public var taskTitle: String

    public init() {}

    public func perform() async throws -> some IntentResult {
        // Wspólna logika
        await TaskRepository.shared.create(title: taskTitle)
        return .result()
    }
}

// Rozszerzenie specyficzne dla platformy w aplikacji
#if os(iOS)
extension SharedCreateTaskIntent {
    // Zachowanie specyficzne dla iOS
    static var openAppWhenRun: Bool = false
}
#endif

Ta architektura utrzymuje pojedynczą bazę kodu intentów, dostosowując zachowanie per platformę.

Testowanie App Intents

App Intents mogą być testowane jednostkowo jak każdy kod Swift.

TaskIntentTests.swiftswift
import XCTest
import AppIntents
@testable import TaskApp

final class TaskIntentTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Reset serwisu dla testów izolowanych
        TaskService.shared.reset()
    }

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

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

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

    func testCompleteTaskIntent() async throws {
        // Given
        let task = TaskService.shared.createTask(
            title: "Zadanie do ukończenia",
            priority: .medium
        )

        var intent = CompleteTaskIntent()
        intent.task = TaskEntity(task: task)

        // When
        _ = try await intent.perform()

        // Then
        let updatedTask = TaskService.shared.fetchTask(id: task.id)
        XCTAssertTrue(updatedTask?.isCompleted ?? false)
    }

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

        let query = TaskEntityQuery()

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

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

Testy weryfikują zachowanie intentów niezależnie od interfejsu systemu.

Najlepsze praktyki i optymalizacje

Kilka wzorców zapewnia wydajne App Intents i optymalne doświadczenie użytkownika.

BestPractices.swiftswift
import AppIntents

// 1. Frazy zlokalizowane
struct LocalizedTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "task.create.title"

    static var description = IntentDescription(
        "task.create.description",
        categoryName: "task.category"
    )

    @Parameter(title: "task.parameter.title")
    var taskTitle: String

    func perform() async throws -> some IntentResult {
        // ...
        return .result()
    }
}

// 2. Prawidłowa obsługa błędów
enum TaskIntentError: Error, CustomLocalizedStringResourceConvertible {
    case taskNotFound
    case invalidInput
    case serviceUnavailable

    var localizedStringResource: LocalizedStringResource {
        switch self {
        case .taskNotFound:
            return "Nie znaleziono zadania."
        case .invalidInput:
            return "Nieprawidłowe dane."
        case .serviceUnavailable:
            return "Usługa tymczasowo niedostępna."
        }
    }
}

struct RobustTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Solidny intent"

    @Parameter(title: "ID")
    var taskId: String

    func perform() async throws -> some IntentResult & ProvidesDialog {
        guard let uuid = UUID(uuidString: taskId) else {
            throw TaskIntentError.invalidInput
        }

        guard let task = TaskService.shared.fetchTask(id: uuid) else {
            throw TaskIntentError.taskNotFound
        }

        return .result(dialog: "Zadanie znalezione: \(task.title)")
    }
}

// 3. Optymalizacja EntityQuery
struct OptimizedTaskQuery: EntityStringQuery {
    // Zoptymalizowane wyszukiwanie tekstowe
    func entities(matching string: String) async throws -> [TaskEntity] {
        // Wyszukiwanie po stronie serwisu z limitem
        TaskService.shared.search(query: string, limit: 10)
            .map { TaskEntity(task: $0) }
    }

    // Ograniczone sugestie dla wydajności
    func suggestedEntities() async throws -> [TaskEntity] {
        TaskService.shared.fetchRecentTasks(limit: 5)
            .map { TaskEntity(task: $0) }
    }
}

// 4. Focus Filter dla trybów Skupienia
struct TaskFocusFilter: SetFocusFilterIntent {
    static var title: LocalizedStringResource = "Filtruj zadania"

    @Parameter(title: "Pokaż tylko wysoki priorytet")
    var showHighPriorityOnly: Bool

    func perform() async throws -> some IntentResult {
        TaskService.shared.setFocusFilter(highPriorityOnly: showHighPriorityOnly)
        return .result()
    }
}

Te wzorce zapewniają płynną integrację z systemem przy zachowaniu optymalnej wydajności.

Podsumowanie

App Intents i Siri Shortcuts transformują sposób, w jaki użytkownicy wchodzą w interakcję z aplikacjami iOS. W 2026 roku, dzięki Apple Intelligence, ujawnianie intentów nie jest już opcjonalne, ale niezbędne do dostarczania nowoczesnego i intuicyjnego doświadczenia.

Lista kontrolna App Intents iOS 18+

  • ✅ Utwórz AppIntents dla głównych akcji aplikacji
  • ✅ Zdefiniuj AppEntities dla danych do manipulacji
  • ✅ Użyj AppEnum dla typów wyliczeniowych
  • ✅ Zaimplementuj AppShortcutsProvider z frazami głosowymi
  • ✅ Przestrzegaj limitu maksymalnie 10 App Shortcuts
  • ✅ Uwzględnij \(.applicationName) we wszystkich frazach
  • ✅ Skonfiguruj ParameterSummary dla feedbacku Siri
  • ✅ Zintegruj domeny Apple Intelligence, jeśli dotyczy
  • ✅ Testuj intenty testami jednostkowymi
  • ✅ Zlokalizuj tytuły i opisy

Zacznij ćwiczyć!

Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.

Tagi

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

Udostępnij

Powiązane artykuły