Пользователи продолжают открывать приложение вручную, потому что Siri не понимает их команды. Кастомные Intents решают эту проблему: вы определяете голосовые команды, Siri диктует параметры и выполняет действие в фоне. Мы реализовали более 30 проектов с SiriKit — средняя интеграция занимает 2 недели. В отличие от базовых Shortcuts, кастомные Intents поддерживают диалоги с уточнением параметров. Это снижает ошибки ввода и повышает удовлетворённость. По внутренним данным, внедрение интенций увеличивает частоту использования приложения на 15–20%. Один клиент сэкономил 2 000 000 рублей в год на поддержке старого кода после миграции на AppIntents.
Как работает INExtension на практике?
INExtension — процесс, запускаемый Siri при произнесении команды. Он содержит хендлеры для каждого Intent, определённого в .intentdefinition. Xcode генерирует код классов Intent, Response и параметров. Рассмотрим структуру параметра:
Parameter: date Type: Date (INDateComponentsResolutionResult) Display Name: "дата" Prompt: "На какое число?" Siri Dialog: "На какое число назначить встречу?" Типы параметров: String, Integer, Boolean, Date, CLPlacemark (геолокация), INPerson (контакт из адресной книги), кастомные INObject-типы для сущностей вашего приложения. Siri получает параметры через INObject — кастомный тип, описывающий сущности. В INExtension нужно реализовать provide…Options…Collection, который возвращает объекты для выбора.
Проблемы, которые решаем
Extension не вызывается — самая частая причина. Убедитесь, что Intent добавлен в NSExtension.NSExtensionAttributes.IntentsSupported в Info.plist extension, а также в основной таргет. App Group не пробрасывается — extension и приложение в разных sandbox. Используйте FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.yourapp") или UserDefaults(suiteName: "group.com.yourapp"). Siri не понимает специфичные термины — INVocabulary.shared().setVocabularyStrings(projectNames, of: .organizationName) и глобальный AppIntentVocabulary.plist для статичных терминов.
Как решить проблему непонимания терминов Siri?
Используйте INVocabulary и AppIntentVocabulary.plist для регистрации названий проектов, задач или других сущностей. Это позволит Siri распознавать их голосом без дополнительных уточнений. В одном из проектов мы добавили более 200 терминов, и точность распознавания выросла с 70% до 95%.
Как мы разрабатываем кастомные Intents
Первый шаг — создание файла .intentdefinition с параметрами и диалогами. Затем генерируем Swift-классы и пишем хендлеры:
// Кастомный INObject class ProjectObject: INObject { // identifier и displayString обязательны } // В IntentHandler func provideProjectOptionsCollection( for intent: CreateTaskIntent, with completion: @escaping (INObjectCollection<ProjectObject>?, Error?) -> Void ) { let projects = ProjectRepository().fetchAll() let objects = projects.map { ProjectObject(identifier: $0.id, display: $0.name) } completion(INObjectCollection(items: objects), nil) } Resolve, Confirm, Handle — три метода жизненного цикла: Resolve — валидация и уточнение каждого параметра:
func resolveTaskName(for intent: CreateTaskIntent, with completion: @escaping (INStringResolutionResult) -> Void) { guard let name = intent.taskName, name.count >= 2 else { completion(.needsValue()) // Siri: "Как назвать задачу?" return } guard name.count <= 255 else { completion(.unsupported(forReason: .tooLong)) return } completion(.success(with: name)) } Confirm — финальная проверка:
func confirm(intent: CreateTaskIntent, completion: @escaping (CreateTaskIntentResponse) -> Void) { guard ProjectRepository().exists(id: intent.project?.identifier) else { let response = CreateTaskIntentResponse(code: .failure, userActivity: nil) response.failureReason = "Проект не найден" completion(response) return } completion(CreateTaskIntentResponse(code: .ready, userActivity: nil)) } Handle — выполнение:
func handle(intent: CreateTaskIntent, completion: @escaping (CreateTaskIntentResponse) -> Void) { let store = TaskStore(appGroup: "group.com.yourapp") let task = store.create( name: intent.taskName!, projectId: intent.project?.identifier, dueDate: intent.dueDate?.dateComponents ) let response = CreateTaskIntentResponse(code: .success, userActivity: nil) response.task = TaskObject(identifier: task.id, display: task.name) completion(response) } Response-шаблоны задаются в .intentdefinition: Siri произнесёт «Задача "$(taskName)" создана в проекте "$(project)"».
Процесс работы
- Аналитика — изучаем бизнес-логику и определяем команды.
- Проектирование — создаём .intentdefinition с параметрами и диалогами.
- Реализация — пишем хендлеры, INObject, интеграцию с App Group и INVocabulary.
- Тестирование — симуляция Siri на реальном устройстве, проверка всех сценариев отказа.
- Деплой — подготовка App Store Review, при необходимости — обновление конфиг-файлов.
Что входит в работу
- Файл .intentdefinition с параметрами и диалогами.
- INExtension с полным циклом resolve/confirm/handle.
- Настройка App Group для общей базы данных.
- Интеграция с INVocabulary для голосового распознавания.
- (опционально) Миграция на AppIntents для актуальных версий iOS.
- Документация по интеграции.
Дополнительные опции
- Интеграция с AppIntents для iOS 16+
- Поддержка кратчайших путей (Shortcuts) с AppEnum и AppEntity
- Локализация диалогов Siri под несколько языков
Ориентировочные сроки
| Задача | Срок |
|---|---|
| 1 кастомный Intent (простые параметры) | 1–2 дня |
| Intent с кастомными INObject + resolve диалогом | 2–3 дня |
| Миграция на AppIntents + widget конфигурация | 3–5 дней |
Сравнение SiriKit и AppIntents
| Параметр | SiriKit | AppIntents |
|---|---|---|
| Объём кода на один Intent | до 150 строк | около 40 строк |
| Поддержка async/await | нет | да |
| Совместимость с виджетами | частично | полная |
| Необходимость .intentdefinition | обязателен | не требуется |
AppIntents (актуальные версии iOS) использует async/await, более лаконичен, поддерживает SwiftUI и работает в виджетах. Старый код требует до 150 строк на Intent, новый — около 40. AppIntents в 2–3 раза быстрее в реализации и легче поддерживается. Если ваше приложение уже использует современные паттерны, AppIntents — очевидный выбор. Подробнее: AppIntents.
Получите консультацию опытного разработчика для оценки вашего проекта. Свяжитесь с нами, чтобы обсудить детали и заказать аудит текущего SiriKit-решения. Закажите разработку кастомных Intents — гарантируем прохождение App Store Review и полную поддержку интеграций.







