How to Build Siri Actions with App Intents in iOS 16

The App Intents framework introduced in iOS 16 fundamentally changes how developers integrate app capabilities with Siri and the Shortcuts app. By replacing the legacy SiriKit Intents definition files with pure Swift code, this framework allows developers to expose custom actions natively without background extensions or complex code generation. This guide details how developers implement the AppIntent protocol, configure dynamic parameters, define natural voice phrases using AppShortcutsProvider, and return visual responses to users.

1. Adopt the AppIntent Protocol

To create an action Siri can run, define a Swift structure that conforms to the AppIntent protocol. The protocol requires a localized title and an asynchronous perform() method that executes the action.

import AppIntents

struct SendMessageIntent: AppIntent {
    static var title: LocalizedStringResource = "Send Message"
    static var description = IntentDescription("Sends a quick message to a contact.")

    func perform() async throws -> some IntentResult {
        // Execute business logic here
        return .result()
    }
}

2. Add Parameters with @Parameter

To enable Siri to collect necessary input from the user (such as recipient names, text, or numbers), decorate properties with the @Parameter property wrapper.

struct SendMessageIntent: AppIntent {
    static var title: LocalizedStringResource = "Send Message"

    @Parameter(title: "Recipient")
    var recipientName: String

    @Parameter(title: "Message Content")
    var message: String

    func perform() async throws -> some IntentResult {
        MessageService.send(message, to: recipientName)
        return .result()
    }
}

If a user invokes the intent without providing all required parameters, Siri automatically prompts the user for the missing values using conversational loops.

3. Expose Custom Data Using AppEntity

For complex types—such as items from a database, contacts, or media collections—conform the data model to AppEntity. An AppEntity requires an EntityQuery so Siri and Shortcuts can look up objects by identifier or string search.

struct ContactEntity: AppEntity {
    static var defaultQuery = ContactQuery()
    static var typeDisplayRepresentation: TypeDisplayRepresentation = "Contact"

    var id: UUID
    var name: String

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(name)")
    }
}

struct ContactQuery: EntityQuery {
    func entities(for identifiers: [UUID]) async throws -> [ContactEntity] {
        // Fetch entities matching identifiers
    }
    
    func suggestedEntities() async throws -> [ContactEntity] {
        // Return quick suggestions for UI pickers
    }
}

4. Provide Zero-Configuration App Shortcuts

In iOS 16, users no longer need to manually configure phrases in the Shortcuts app before invoking them with Siri. Developers declare ready-to-use voice commands by conforming a structure to AppShortcutsProvider.

struct AppShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: SendMessageIntent(),
            phrases: [
                "Send a message with \(.applicationName)",
                "Message \(\.$recipientName) using \(.applicationName)"
            ],
            shortTitle: "Send Message",
            systemImageName: "message.fill"
        )
    }
}

Whenever the app is installed or updated, iOS automatically indexes these phrases. Users can immediately speak phrases like, "Hey Siri, send a message with MyApp."

5. Return Dialog and Visual Feedback

The perform() method returns an instance conforming to IntentResult. Developers can provide spoken responses, visual SwiftUI dialogs, or value outputs directly in the Siri interface.

func perform() async throws -> some IntentResult & ReturnsValue<Bool> & ProvidesDialog {
    let success = MessageService.send(message, to: recipientName)
    
    return .result(
        value: success,
        dialog: IntentDialog("Message sent to \(recipientName).")
    )
}

By leveraging these programmatic declarations, developers gain type safety, fast compile-time verification, and deep integration with iOS 16 system surfaces including Siri, Spotlight, and the Shortcuts app.