<!--
{
  "availability" : [
    "iOS: 27.0.0 -",
    "iPadOS: 27.0.0 -",
    "macCatalyst: -",
    "macOS: 27.0.0 -",
    "tvOS: 27.0.0 -",
    "visionOS: 27.0.0 -",
    "watchOS: 27.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "AppIntents",
  "identifier" : "/documentation/AppIntents/LongRunningIntent/performBackgroundTask(options:operation:onCancel:)",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "App Intents",
      "AppIntents"
    ],
    "preciseIdentifier" : "s:10AppIntents17LongRunningIntentPAAE21performBackgroundTask7options9operation8onCancelqd__AA0cdH7OptionsV_qd__yYaKcyAA0E18CancellationReasonVYbctYaKAA011CancellableE0RzlF"
  },
  "title" : "performBackgroundTask(options:operation:onCancel:)"
}
-->

# performBackgroundTask(options:operation:onCancel:)

Runs an operation in the background and provides a way to cancel the operation
before it finishes.

```
@discardableResult func performBackgroundTask<T>(options: LongRunningTaskOptions = [], operation: @escaping () async throws -> T, onCancel: @escaping @Sendable (IntentCancellationReason) -> Void) async throws -> T where Self : CancellableIntent
```

## Parameters

`options`

Additional options to configure the runtime behavior. For example, you
might use this parameter to tell the system that your task requires GPU resources.
The default value for this parameter is an empty set.

`operation`

The closure to run in the background. Use this closure to specify the
code for your app intent’s task. The closure takes no parameters and returns a
type that you specify.

`onCancel`

The closure to run when cancellation occurs. Use this closure to
respond to the cancellation and perform any required cleanup. The closure receives
a parameter with the cancellation reason and returns no value. The system runs this
closure instead of the [`withIntentCancellationHandler(operation:onCancel:isolation:)`](/documentation/AppIntents/CancellableIntent/withIntentCancellationHandler(operation:onCancel:isolation:))
method from the [`CancellableIntent`](/documentation/AppIntents/CancellableIntent) protocol.

## Return Value

The value you return from the `operation` closure.

## Discussion> Throws: Throws an error if the operation fails or the system can’t run the operation.

If your app intent also conforms to the [`CancellableIntent`](/documentation/AppIntents/CancellableIntent) protocol, use this method to
wrap long-running code in your app intent’s [`perform()`](/documentation/AppIntents/AppIntent/perform()) method. This method
automatically extends the amount of time your code has to run in the background past the
standard 30-second limit present on some platforms. You don’t have to start a separate
background task. If someone cancels the task for any reason, the system runs your
cancellation handler before stopping the task.

While your operation runs, provide regular progress updates using the [`progress`](/documentation/AppIntents/ProgressReportingIntent/progress)
property of the inherited [`ProgressReportingIntent`](/documentation/AppIntents/ProgressReportingIntent) protocol. If you don’t update this
property regularly, the system can cancel the background runtime extension and end your
task prematurely.

Live Activities displays the progress of your app intent’s task using information it receives
automatically from this method. Live Activities displays the values of the
<doc://com.apple.documentation/documentation/Foundation/Progress/localizedDescription> and
<doc://com.apple.documentation/documentation/Foundation/Progress/localizedAdditionalDescription>
properties as the title and subtitle of your task. It also displays a progress bar, which it
configures using the values in the <doc://com.apple.documentation/documentation/Foundation/Progress/completedUnitCount>
and <doc://com.apple.documentation/documentation/Foundation/Progress/totalUnitCount> properties.

The following example shows the [`perform()`](/documentation/AppIntents/AppIntent/perform()) method of an app intent, which uses
this method to extend the background runtime of the task. The method implementation uploads a
file in chunks and updates progress values after each chunk. If someone cancels the task, the
call to <doc://com.apple.documentation/documentation/Swift/Task/checkCancellation()> throws
an error that this method catches and uses to run your cancellation handler.

```swift
struct UploadFileIntent: LongRunningIntent, CancellableIntent {
    func perform() async throws -> some IntentResult {
        return try await performBackgroundTask {
            progress.totalUnitCount = 100
            for chunk in 0..<100 {
                try Task.checkCancellation()
                await uploadChunk(chunk)
                progress.completedUnitCount = Int64(chunk + 1)
            }
            return .result()
        } onCancel: { reason in
            cleanup(for: reason)
        }
    }
}
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)