Swift Academy · Lesson

App Intents and Shortcuts

Expose actions to Siri and Shortcuts.

Lesson 4 of 413 steps

App Intents and Shortcuts is a free Swift Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, and your progress syncs across the web and the CoddyKit app. The Swift Academy course includes 4 lessons in total.

What App Intents Are

The App Intents framework exposes your app's actions to the system — Siri, Shortcuts, Spotlight, widgets, and the Action button. You describe an action once as a Swift type, and it becomes available everywhere, voice-driven and automatable.

import AppIntents
// Define an action as a type; the system can run it
// from Siri, Shortcuts, Spotlight, widgets, etc.

Defining an AppIntent

An intent conforms to AppIntent, declares a user-facing title, and implements perform() which does the work and returns a result. The framework discovers it automatically — no registration needed.

import AppIntents
struct AddTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Add Task"
    func perform() async throws -> some IntentResult {
        // create the task here
        return .result()
    }
}

Parameters

Use the @Parameter property wrapper to ask the user (or Siri) for input. The system prompts for missing values and validates them. Each parameter has a title shown in the Shortcuts editor.

import AppIntents
struct AddTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Add Task"
    @Parameter(title: "Title")
    var taskTitle: String
    func perform() async throws -> some IntentResult {
        return .result()
    }
}

Returning Values and Dialog

An intent can return data and speak a confirmation. IntentResult variants like .result(value:dialog:) let you return a typed value plus a spoken/visible dialog Siri reads back to the user.

import AppIntents
struct CountTasksIntent: AppIntent {
    static var title: LocalizedStringResource = "Count Tasks"
    func perform() async throws
        -> some IntentResult & ProvidesDialog {
        let count = 5
        return .result(
            dialog: "You have \(count) tasks")
    }
}

Parameter Summary

parameterSummary describes the sentence shown in the Shortcuts editor, weaving parameters into natural language like Add \(taskTitle) to my list. It makes your action read clearly when composed into shortcuts.

import AppIntents
struct AddTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "Add Task"
    @Parameter(title: "Title") var taskTitle: String
    static var parameterSummary: some ParameterSummary {
        Summary("Add \(\.$taskTitle) to my list")
    }
    func perform() async throws -> some IntentResult {
        .result()
    }
}

Entities

An AppEntity represents a model object the system can reason about — a task, a note, a playlist. With an entity and a query, Siri and Shortcuts can let users pick from your data as a parameter value.

import AppIntents
struct TaskEntity: AppEntity {
    static var typeDisplayRepresentation:
        TypeDisplayRepresentation = "Task"
    var id: String
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(id)")
    }
    static var defaultQuery = TaskQuery()
}

Entity Queries

An EntityQuery tells the system how to find your entities by id and how to list suggestions. This powers the picker the user sees when choosing a value in Shortcuts or answering Siri.

import AppIntents
struct TaskQuery: EntityQuery {
    func entities(for ids: [String]) async throws
        -> [TaskEntity] {
        ids.map { TaskEntity(id: $0) }
    }
    func suggestedEntities() async throws -> [TaskEntity] {
        [TaskEntity(id: "Groceries")]
    }
}

App Shortcuts

An AppShortcut makes an intent runnable by voice with zero setup — no need for the user to build a shortcut first. You supply trigger phrases that must include the app name token so Siri knows the context.

import AppIntents
struct AddTaskShortcut: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: AddTaskIntent(),
            phrases: ["Add a task in \(.applicationName)"],
            shortTitle: "Add Task",
            systemImageName: "plus")
    }
}

Trigger Phrases

Phrases must contain \(.applicationName) so Siri can disambiguate. Provide several natural variations users might say. The system handles matching, so you do not parse language yourself.

import AppIntents
// Provide variants; applicationName is required:
// phrases: [
//   "Add a task in \(.applicationName)",
//   "Create a task with \(.applicationName)",
//   "New \(.applicationName) task"
// ]
let phrases = "include applicationName token"
_ = phrases

Surfacing Beyond Siri

Because intents are declarative, the same AddTaskIntent can power an interactive widget Button(intent:), a Control Center control, or a Shortcuts action — all running your perform() without extra plumbing.

import AppIntents
import SwiftUI
// In an interactive widget:
// Button(intent: AddTaskIntent()) {
//     Label("Add", systemImage: "plus")
// }
let reuse = "one intent, many surfaces"
_ = reuse

Localizing Intents

Titles and dialog use LocalizedStringResource, so they translate via your String Catalog. Trigger phrases are localized per language too, letting Siri respond to users in their own tongue.

import AppIntents
struct GreetIntent: AppIntent {
    static var title: LocalizedStringResource = "Greet"
    func perform() async throws
        -> some IntentResult & ProvidesDialog {
        .result(dialog: "Welcome back")
    }
}

Quick Check

Recall what makes an AppShortcut's phrases valid.

Recap

You learned App Intents:

  • Conform to AppIntent with a title and perform(); collect input via @Parameter and describe it with parameterSummary.
  • Model data as AppEntity with an EntityQuery for pickers and suggestions.
  • Expose voice actions through AppShortcut phrases that include \(.applicationName).
  • The same intent powers Siri, Shortcuts, interactive widgets, and controls, and localizes via LocalizedStringResource.
Free to start

Learn Swift with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
122
Lessons
409

Frequently Asked Questions

Is the “App Intents and Shortcuts” lesson free?

Yes — any 3 lessons of the Swift Academy learning path, including “App Intents and Shortcuts”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Swift Academy course includes 4 lessons in total.

What will I learn in “App Intents and Shortcuts”?

Expose actions to Siri and Shortcuts. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Swift Academy?

No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “App Intents and Shortcuts” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Swift Academy lesson?

Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Building a WidgetKit Widget
  2. Timeline Providers and Snapshots
  3. App Extensions Overview
  4. App Intents and Shortcuts
← Back to Swift Academy