Разработка
Делаем первый App Shortcut
Одна из моих любимых особенностей создания действий приложения с помощью App Intents — простота создания прототипов. Я могу пройти путь от идеи до работающего действия менее чем за час. В этом руководстве я расскажу вам о том, как создать первое действие для приложения Shortcuts.
В iOS 16 компания Apple запустила фреймворк App Intents, позволяющий разработчикам легче интегрировать действия своих приложений в систему. Действия приложений могут использоваться в различных частях системы, таких как виджеты, приложение Shortcuts, Siri и Spotlight. До появления фреймворка App Intents мы использовали SiriKit для передачи наших действий в систему, но эта платформа имела более высокий барьер для входа из-за недостатка документации и ресурсов.
Одна из моих любимых особенностей создания действий приложения с помощью App Intents — простота создания прототипов. Я могу пройти путь от идеи до работающего действия менее чем за час. В этом руководстве я расскажу вам о том, как создать первое действие для приложения Shortcuts.
Созданное нами действие будет доступно системе при первой установке нашего приложения и сразу же станет доступно Siri. Однако в данном руководстве мы не будем рассматривать взаимодействие между действием и Siri — мы сосредоточимся на том, как пользователь может использовать ваше действие в Shortcuts.
Прежде чем начать, давайте рассмотрим, что нам нужно сделать для создания простого ярлыка:
- Соответствовать протоколу AppIntent.
- Добавить описание
- Добавить параметр(ы)
- Обработать пользовательский ввод в методе
perform
Соответствие протоколу AppIntent
Начните с соответствия протоколу AppIntents. Это можно сделать, присвоив действию название, а затем добавив метод perform
.
import AppIntents
struct AddTaskIntent: AppIntent {
static var title: LocalizedStringResource = "Add task"
func perform() async throws -> some IntentResult {
return .result()
}
}
Здесь:
title
: Заголовок ярлыка, который будет отображаться в приложении ярлыков.perform()
: Методperform
непосредственно выполняет действие интента. Например:- Cохраняет данные после того, как пользователь выполнил ввод.
- Показывает новый запрос, если система обнаруживает двусмысленность из-за нескольких значений.
- Отображает представление после выполнения действия.
Если вы хотите открыть приложение после выполнения действия, установите свойство openAppWhenRun
в true
.
Первая задача выполнена!
Добавление описания
Описание говорит нам о цели интента — это необязательное свойство, но мы добавим его сюда в качестве следующего шага.
xxxxxxxxxx
import AppIntents
struct AddTaskIntent: App Intent {
static var title: LocalizedStringResource = "Add task"
static var description: IntentDescription? = "This action allows you to add a new task to your to-do list "
func perform() async throws -> some IntentResult {
return .result()
}
}
Добавление параметров
В нашем примере мы хотим, чтобы пользователь мог добавить задачу, введя ее в текстовое поле или обратившись к Siri. Чтобы это произошло, мы добавим параметр для получения пользовательского ввода. Параметры могут быть разных типов, от примитивных до более сложных типов, таких как IntentPerson
. Полный список возможных типов параметров приведен на этой странице документации.
xxxxxxxxxx
import Foundation
import AppIntents
struct AddTaskIntent: App Intent {
@Parameter(title: "Task")
var task: String
static var title: LocalizedStringResource = "Add task"
static var description: IntentDescription? = "This action allows you to add a new task to your to-do list "
func perform() async throws -> some IntentResult {
return .result()
}
}
Мы можем добавить другие свойства в обертку свойства параметра, например:
description
описывает, что представляет собой данное свойство. Описание, добавленное к параметрам, будет отображаться в описании действия приложения.inputOptions
описывает, как мы хотим стилизовать вводимые данные при использовании приложения Shortcuts. Он имеет такие свойства, какkeyboardType
,capitalizationType
,multiline
,autocorrect
и другие.requestValueDialog
описывает точную фразу, которую мы хотим произнести в аудиоконтексте.requestDisambiguationDialog
описывает фразу, которую мы хотим произнести в случае нескольких значений — Siri попросит пользователя выбрать одно из них.
Наш параметр добавляется в виде строки под заголовком. Мы можем сделать его более красивым, добавив ParameterSummary
. ParameterSummary
— это предложение, представляющее намерение и его параметры. Apple рекомендует предоставлять резюме параметров, чтобы сделать пользовательский интерфейс более упорядоченным.
xxxxxxxxxx
import Foundation
import AppIntents
struct AddTaskIntent: App Intent {
@Parameter(title: "Task")
var task: String
static var title: LocalizedStringResource = "Add task"
static var description: IntentDescription? = "This action allows you to add a new task to your to-do list "
static var parameterSummary: some ParameterSummary {
Summary("Add \(\.$task)")
}
func perform() async throws -> some IntentResult {
return .result()
}
}
В данном примере при запуске ярлыка отображается текстовое поле. Нажатие кнопки «Готово» приводит к его удалению, но дальнейшего взаимодействия не происходит.
В зависимости от наличия знака ?
система рассматривает параметр как обязательный или нет. Если вы не добавите знак ?
, система предложит пользователю ввести параметр — при наличии знака ?
система продолжит выполнение действия. Если вы хотите запросить значение параметра, используйте .needsValueError()
с диалогом, который вы хотите, чтобы система использовала для запроса пользователя.
needsValueError(_:)
Возвращает ошибку restartPerform с контекстом для запроса у пользователя значения этого параметра и повторного выполнения намерения с новыми значениями. — Apple
xxxxxxxxxx
import Foundation
import AppIntents
struct AddTaskIntent: App Intent {
@Parameter(title: "Task")
var task: String
static var title: LocalizedStringResource = "Add task"
static var description: IntentDescription? = "This action allows you to add a new task to your to-do list "
static var parameterSummary: some ParameterSummary {
Summary("Add \(\.$task)")
}
func perform() async throws -> some IntentResult {
guard let task = task else {
throw $task.needsValueError("What task would you like to add?")
}
return .result()
}
}
Обработка пользовательского ввода в методе perform
После определения того, какой ввод ожидается от пользователя, необходимо сделать то, что нужно приложению. В данном примере необходимо сохранить вводимые данные в задаче, которая будет храниться локально на устройстве. В методе perform
задача создается, а затем сохраняется. После этого отображается текстовое представление об успешном сохранении.
xxxxxxxxxx
import Foundation
import AppIntents
import SwiftUI
struct AddTaskIntent: App Intent {
@Parameter(title: "Task")
var task: String
static var title: LocalizedStringResource = "Add task"
static var description: IntentDescription? = "This action allows you to add a new task to your to-do list "
static var parameterSummary: some ParameterSummary {
Summary("Add \(\.$task)")
}
private let persistenceController: PersistenceController = .shared
@MainActor
func perform() async throws -> some ShowsSnippetView {
try persistenceController.addTask(Task(title: task, createDate: .now))
return .result(view: Text("Task added successfully"))
}
}
Метод perform
выполняется, когда система разрешила все параметры, необходимые вашему коду для успешного выполнения его функциональности. При реализации задач в методе perform
добавляемая логика должна выполнить необходимую работу, которая вернет системе нужное значение. Таким результатом может быть значение, которое шорткат может использовать в последующих связанных действиях, диалог для отображения, представление сниппета SwiftUI и т.д. Если интенту нет смысла возвращать конкретный результат, верните .result()
, чтобы сообщить системе о завершении намерения.
Если намерение манипулирует пользовательским интерфейсом приложения, аннотируйте perform() с помощью @MainActor, чтобы убедиться, что функция выполняется в главной очереди. — Apple
Примечание: Когда мы указываем значения, возвращаемые из метода perform:
- Если вы возвращаете представление SwiftUI, укажите возвращаемый тип как
ShowsSnippetView
. - Если вы возвращаете значение из метода perform, укажите
ReturnsValue<T>
, а в круглых скобках укажите тип, который вы хотите вернуть. Если предоставить это значение без указания типа, то это приведет к аварийному завершению работы приложения. - Если вы хотите, чтобы Siri произнесла фразу, верните
ProvidesDialog
, указав, что должна произнести Siri. - Если необходимо вернуть несколько типов, укажите каждый тип, разделив их знаком
&
. Например:ShowsSnippetView & ProvidesDialog & ReturnsValue<T>
.
Теперь, когда мы выполнили все шаги, у нас есть основа для намерения! Используя полученные знания, мы можем создавать и более сложные сценарии использования — мы рассмотрим их в одной из следующих статей.
-
Новости2 недели назад
Видео и подкасты о мобильной разработке 2025.14
-
Разработка4 недели назад
«Давайте просто…»: системные идеи, которые звучат хорошо, но почти никогда не работают
-
Видео и подкасты для разработчиков3 недели назад
Исследуем мир фото и видео редакторов
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.13