Shortcuts (Apple) Integration in Mobile Applications
The Shortcuts application (Quick Commands) allows users to create automations from actions of different applications. If your application provides App Intents, the user can include it in any automation: "When I arrive home—open my playlist in [your app] and turn on the lights". Shortcuts integration is not just "voice command support", it's participation in Apple's automation ecosystem.
App Intents — The Right Path Since iOS 16
Before iOS 16, integration was based on SiriKit with .intentdefinition files and INExtension in a separate target. Since iOS 16—AppIntents framework. Less boilerplate, no code generation, the Intent is immediately visible in Shortcuts without additional setup.
Minimal Intent for Shortcuts:
struct StartWorkoutIntent: AppIntent {
static var title: LocalizedStringResource = "Start Workout"
static var description = IntentDescription(
"Starts a workout in the application",
categoryName: "Workouts"
)
static var openAppWhenRun: Bool = false // don't open the application
@Parameter(title: "Workout Type")
var workoutType: WorkoutType
func perform() async throws -> some IntentResult & ProvidesDialog {
try await WorkoutService.shared.start(type: workoutType)
return .result(dialog: "Workout \(workoutType.name) started")
}
}
openAppWhenRun: Bool = false is key for automations. Intent executes in the background without opening the application. For Shortcuts, this is critical—otherwise the screen flashes and your UI opens during automation.
Parameters and Dynamic Values
Static parameters (String, Int, Bool, Date)—just properties with @Parameter. Dynamic—through AppEntity with AppEntityQuery.
enum WorkoutType: String, AppEnum {
case running, cycling, swimming
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Workout Type")
static var caseDisplayRepresentations: [WorkoutType: DisplayRepresentation] = [
.running: "Running",
.cycling: "Cycling",
.swimming: "Swimming"
]
}
AppEnum is a closed list. AppEntity + AppEntityQuery—a dynamic list from the application's database. If the user added a custom workout type, it should appear in Shortcuts as an option—only through AppEntityQuery.entities(matching:).
Results and Data Transfer Between Actions
Shortcuts allows passing one action's result to another. For this, Intent must return a specific type, not just a dialog.
func perform() async throws -> some IntentResult & ReturnsValue<WorkoutSummary> {
let summary = try await WorkoutService.shared.getLastSummary()
return .result(value: summary)
}
WorkoutSummary is a structure with AppEntity or a basic type. Now the next block in Shortcuts can receive this data as a parameter.
App Shortcuts: Phrases Without Setup
AppShortcutsProvider—phrases that work without manual user setup:
struct FitnessAppShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: StartWorkoutIntent(),
phrases: [
"Start a workout in \(.applicationName)",
"Launch \(.applicationName)"
],
shortTitle: "Start Workout",
systemImageName: "figure.run"
)
}
static var shortcutTileColor: ShortcutTileColor = .teal
}
A phrase with \(.applicationName) is mandatory. Apple checks for the application name in the phrase in review. Without it—rejection.
iOS 17+ allows using parameters directly in phrases: "Start running in (.applicationName)"—Siri recognizes "running" as the workoutType parameter value.
Widgets and Shortcuts Together
iOS 17+ widget buttons use the same AppIntent. One Intent—works as an action in Shortcuts, widget button, and voice command. This significantly simplifies development: logic written once.
Testing
In simulator: Settings → Siri & Search → [app]—shows registered Intents. The Shortcuts app on simulator allows adding Intent to automation manually and executing.
For App Shortcuts: XCTest with XCTOSSignpostExpectation or simply launch through Shortcuts.app and check the result.
Timeline
Basic integration 3–5 Intent without AppEntity: 2–4 weeks. Full integration with AppEntity, App Shortcuts, value transfer between actions: 5–9 weeks. Migration from SiriKit Intents to App Intents: 3–6 weeks. Cost depends on quantity and complexity of actions.







