[SC]()

iOS. Apple. Indies. Plus Things.

Confirmation and Result Interactive Snippets

// Written by Jordan Morgan // Jul 10th, 2025 // Read it in about 4 minutes // RE: App Intents

This post is brought to you by Emerge Tools, the best way to build on mobile.

Recently, on the Superwall blog, I wrote up a guide over interactive snippets. If you haven’t checked that out, I’d go there first. Continuing on that same beat, I wanted to also highlight an important difference in interactive snippets.

There are two types you can provide:

  1. Result snippets: These show data that you don’t have to confirm (i.e. here’s how much caffeine you’ve had today).
  2. Confirmation snippets: These show data, but also require you to make some sort of decision before continuing (i.e here’s some coffee I want to order).

Both of them are interactive, and can have buttons or toggles that fire intents. At the API level, they both have the same signatures. However, confirmation snippets request said confirmation inside of the perform function. From Apple’s sample code:

struct FindTicketsIntent: AppIntent {

    func perform() async throws -> some IntentResult & ShowsSnippetIntent {
        let searchRequest = await searchEngine.createRequest(landmarkEntity: landmark)

        // Kicks off a confirmation snippet here
        try await requestConfirmation(
            actionName: .search,
            snippetIntent: TicketRequestSnippetIntent(searchRequest: searchRequest)
        )

        // Resume searching...
    }
}

And that is where things diverge. To understand that divergence better, consider that interactive snippets are typically dismissed by the user tapping the system provided “Done” button found below them:

Result type of an interactive snippet.

All “result” interactive snippets work this way. Alternatively, they can also just swipe it away to yeet it out of there.

But when you need confirmation, the “Done” button isn’t displayed, and instead the system will show contextualized buttons based on the actionName parameter. In the code above, that was set to “.search”, and so it is — you get a “Cancel” and “Search” button:

Confirmation type of an interactive snippet.

And then the intent carries on, here’s the full sample, I’ve edited the comment to demonstrate the flow better:

struct FindTicketsIntent: AppIntent {

    static let title: LocalizedStringResource = "Find Tickets"

    static var parameterSummary: some ParameterSummary {
        Summary("Find best ticket prices for \(\.$landmark)")
    }
    
    @Dependency var searchEngine: SearchEngine

    @Parameter var landmark: LandmarkEntity

    func perform() async throws -> some IntentResult & ShowsSnippetIntent {
        let searchRequest = await searchEngine.createRequest(landmarkEntity: landmark)

        // The new UI shows here, so you can think of `TicketRequestSnippetIntent`
        // As its own confirmation snippet. Once the user is done and they tap search,
        // We'll come back right here, and the search engine code will fire
        try await requestConfirmation(
            actionName: .search,
            snippetIntent: TicketRequestSnippetIntent(searchRequest: searchRequest)
        )

        // This happens after the confirmation of the number of tickets is done
        try await searchEngine.performRequest(request: searchRequest)

        // And finally, a new snippet is shown
        return .result(
            snippetIntent: TicketResultSnippetIntent(
                searchRequest: searchRequest
            )
        )
    }
}

What can be tricky here is that this flow shown today technically uses three different interactive snippets:

1. First, there’s the ClosestLandmarkIntent, which returns that landmark view:

Result type of an interactive snippet.

2. Then, tapping “Find Best Ticket Prices” takes us to the above code, where TicketRequestSnippetIntent asks for confirmation on the ticket count:

Result type of an interactive snippet.

3. And, it circles back to TicketResultSnippetIntent to show the results. If you tap “Book Now”, we go back to first step:

Result type of an interactive snippet.

I hope that helps clear up when you’d use a “result” interactive snippet versus a confirmation one. Just because Apple refers to result interactive snippets as a result of something, they are very much well-suited to powerful tasks complete with interactivity.

Now go forth, and make all quick, impactful interactions a snippet!

Until next time ✌️

···

Spot an issue, anything to add?

Reach Out.