---
title: CancellableIntent
framework: appintents
role: symbol
role_heading: Protocol
path: appintents/cancellableintent
---

# CancellableIntent

An interface to support the graceful cancellation of your app intent’s task.

## Declaration

```swift
protocol CancellableIntent : AppIntent
```

## Mentioned in

Creating your first app intent

## Overview

Overview This protocol adds cancellation support to your app intent types. Use it to let the system know that you need additional time to perform cleanup operations when your app intent receives a cancellation notification. To use this protocol, use the withIntentCancellationHandler(operation:onCancel:isolation:) method to wrap your app intent’s task. With this method in place, the system gives your code extra time to handle cancellation before the app intent’s task ends. The system can cancel an app intent for the following reasons: The app intent didn’t report progress and exceeded its 30-second runtime limit. Someone monitoring the progress of the app intent in Siri, Live Activities, or Shortcuts chose to cancel the task. Swift provides the standard withTaskCancellationHandler(handler:operation:) function for tasks to handle cancellation. You can use that function in your app intent’s perform() method to perform any cleanup tasks if you don’t need to know the reason cancellation occurred. If you want to know the reason for cancellation, use the withIntentCancellationHandler(operation:onCancel:isolation:) method that this protocol offers instead. When cancellation occurs, stop your app intent’s current task, release any allocated memory or resources, save intermediate state as needed, and write out any relevant diagnostic information related to the cancellation. The following example shows a payment-processing app intent and the basic code it uses to perform its task. The app intent’s perform() method calls the withIntentCancellationHandler(operation:onCancel:isolation:) method to process the payment and handle cancellation if it occurs. The cancellation handler performs different tasks based on whether the someone canceled the operation deliberately or the system timed out. enum PaymentMethod: String, AppEnum {     case creditCard     case debitCard

static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Payment Method")     static var caseDisplayRepresentations: [PaymentMethod: DisplayRepresentation] = [         .creditCard: "Credit Card",         .debitCard: "Debit Card"     ] }

class PaymentService {     func initiateTransaction(_ id: UUID, amount: Decimal) async throws {         // Initiate payment transaction     }

func authorize(_ id: UUID, method: PaymentMethod) async throws {         // Authorize payment     }

func process(_ id: UUID) async throws {         // Process payment     }

func rollback(_ id: UUID, reason: String) async throws {         // Roll back transaction     }

func cancel(_ id: UUID, reason: String) async throws {         // Cancel transaction     } }

struct ProcessPaymentIntent: AppIntent, ProgressReportingIntent, CancellableIntent {     static var title: LocalizedStringResource = "Process Payment"

@Parameter var amount: Decimal     @Parameter var paymentMethod: PaymentMethod

private let paymentService = PaymentService()

func perform() async throws -> some IntentResult & ProvidesDialog {         let transactionID = UUID()

return try await withIntentCancellationHandler {             updateProgress(fractionCompleted: 0.0, message: "Initiating payment...")             try await paymentService.initiateTransaction(transactionID, amount: amount)

updateProgress(fractionCompleted: 0.3, message: "Authorizing payment...")             try await paymentService.authorize(transactionID, method: paymentMethod)

updateProgress(fractionCompleted: 0.7, message: "Processing payment...")             try await paymentService.process(transactionID)

updateProgress(fractionCompleted: 1.0, message: "Payment complete")             return .result(dialog: "Payment of \(amount) processed successfully")         } onCancel: { reason in             Task {                 switch reason {                 case .timeout:                     try? await paymentService.rollback(transactionID, reason: "timeout")                 case .userCancelled:                     try? await paymentService.cancel(transactionID, reason: "user_cancelled")                 default:                     try? await paymentService.cancel(transactionID, reason: "unknown")                 }             }         }     } } important: Design your cancellation handlers to finish their tasks quickly. On all platforms except macOS, the system can still suspend the process shortly after cancellation. However, supporting this protocol provides additional time compared to app intents that don’t support this protocol.

## Topics

### Cancelling the intent

- [withIntentCancellationHandler(operation:onCancel:isolation:)](appintents/cancellableintent/withintentcancellationhandler(operation:oncancel:isolation:).md)
- [IntentCancellationReason](appintents/intentcancellationreason.md)

## Relationships

### Inherits From

- [AppIntent](appintents/appintent.md)
- [PersistentlyIdentifiable](appintents/persistentlyidentifiable.md)
- [Sendable](swift/sendable.md)
- [SendableMetatype](swift/sendablemetatype.md)

## See Also

### Add-on behaviors

- [UndoableIntent](appintents/undoableintent.md)
- [LongRunningIntent](appintents/longrunningintent.md)
- [PredictableIntent](appintents/predictableintent.md)
- [IntentPrediction](appintents/intentprediction.md)
