Разработка кастомных Intents для Siri

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Разработка кастомных Intents для Siri
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Разработка кастомных Intents для Siri

Кастомные Intents — следующий уровень после базовой интеграции Siri Shortcuts. Вместо простого «открой такой-то экран» пользователь получает полноценный диалог: Siri уточняет параметры, обрабатывает команду в фоне, возвращает результат голосом. Всё это работает без открытия приложения через INExtension.

Структура кастомного Intent

Файл .intentdefinition — центральный элемент. Xcode генерирует из него Swift-код: классы Intent, Response, параметры с типами. Структура параметра:

Parameter: date
  Type: Date (INDateComponentsResolutionResult)
  Display Name: "дата"
  Prompt: "На какое число?"
  Siri Dialog: "На какое число назначить встречу?"

Типы параметров: String, Integer, Boolean, Date, CLPlacemark (геолокация), INPerson (контакт из адресной книги), кастомные INObject-типы для сущностей вашего приложения.

Кастомный INObject нужен, когда параметр — это сущность из вашей базы данных (проект, задача, трек):

// Автогенерировано из .intentdefinition
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)
}

Siri покажет список проектов для выбора — либо пользователь произнесёт название, либо Siri уточнит.

Resolve, Confirm, Handle

Жизненный цикл Intent — три метода:

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)"» с подстановкой реальных значений.

Интеграция с Shortcuts app

INShortcut + INVoiceShortcutCenter позволяют добавить shortcut прямо из приложения без перехода в Settings:

func addToSiri(intent: CreateTaskIntent) {
    let shortcut = INShortcut(intent: intent)
    let vc = INUIAddVoiceShortcutViewController(shortcut: shortcut)
    vc.delegate = self
    present(vc, animated: true)
}

Кнопка «Добавить в Siri» с нативным вью — стандартный паттерн для onboarding.

Интеграция с Widgets через AppIntents (iOS 16+)

С iOS 16 кастомные Intents мигрировали на новый фреймворк AppIntents. Старый SiriKit Intents (.intentdefinition) продолжает работать, но для виджетов конфигурируемых через Shortcuts нужен AppIntent:

struct CreateTaskAppIntent: AppIntent {
    static var title: LocalizedStringResource = "Создать задачу"

    @Parameter(title: "Название задачи")
    var taskName: String

    @Parameter(title: "Проект")
    var project: ProjectEntity?

    func perform() async throws -> some IntentResult & ProvidesDialog {
        let task = try await TaskService().create(name: taskName, project: project?.id)
        return .result(dialog: "Создана задача \(task.name)")
    }
}

AppIntents — это будущее SiriKit на iOS 16+. Меньше boilerplate, поддержка Swift concurrency, работает в виджетах, Spotlight, Shortcuts app.

Типичные проблемы

Extension не вызывается — самая частая проблема. Причины: Intent не добавлен в NSExtension.NSExtensionAttributes.IntentsSupported в Info.plist extension; или Intent добавлен в основной таргет, но не в extension-таргет.

App Group не пробрасывается — Extension и основное приложение работают в разных sandbox. Данные через App Group: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.yourapp") или UserDefaults(suiteName: "group.com.yourapp").

Siri не понимает специфичные терминыINVocabulary.shared().setVocabularyStrings(projectNames, of: .organizationName) и глобальный AppIntentVocabulary.plist для статичных терминов.

Ориентиры по срокам

Задача Срок
1 кастомный Intent (простые параметры) 1–2 дня
Intent с кастомными INObject + resolve диалогом 2–3 дня
Миграция на AppIntents (iOS 16+) + widget конфигурация 3–5 дней