An interface you use to extend the background execution time of an app intent
that performs a long-running task.
This protocol allows an app intent to run for an extended period of time in the
background. When a task runs in the background, the system traditionally gives it
up to 30 seconds to finish its task. For some types of tasks, this amount
of time can be insufficient to complete the task. For example, file operations,
data synchronization, machine learning inference, and data processing tasks can
take longer if they operate on a sufficiently large amount of data. If your app
intent performs a task that might exceed the built-in time limits, incorporate
this protocol and use its methods to perform that task.
In the implementation of your app intent, place the code for your task inside one of
the methods this protocol offers. The methods of this protocol work with the system
to extend the amount of time your code has to run. While your code runs, the system
requires you to report progress regularly, which you do using the ``ProgressReportingIntent/progress``
property of the inherited ``ProgressReportingIntent`` protocol. If you don’t update
this property regularly, the system can cancel the background runtime extension
and end your task prematurely.
The following example shows the implementation of an app intent that uploads a file.
The implementation uploads the file in chunks, and updates the ``ProgressReportingIntent/progress``
property after each chunk.
```swift
struct UploadFileIntent: LongRunningIntent {
static var title: LocalizedStringResource = "Upload Large File"
@Parameter(title: "File")
var file: IntentFile
func perform() async throws -> some IntentResult & ReturnsValue<String> {
// Use performBackgroundTask - zero required parameters!
let result = try await performBackgroundTask {
// This code runs with extended execution time
progress.totalUnitCount = 100
progress.localizedDescription = "Uploading file"
for chunk in 0..<100 {
try Task.checkCancellation()
await uploadChunk(chunk)
progress.completedUnitCount = Int64(chunk + 1)
progress.localizedAdditionalDescription = "\(chunk + 1)% complete"
}
return "Upload complete!"
}
return .result(value: result)
}
private func uploadChunk(_ chunk: Int) async {
// Simulate uploading a chunk
}
}
```
> Note: In macOS, the system allows background tasks to run without time limits. In iOS,
iPadOS, tvOS, visionOS, and watchOS, the system gives tasks 30 seconds to run in the background
unless you use the methods of this protocol to extend that runtime.
Runs an operation in the background with an extended amount of time.
- 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.
- Returns: The value you return from the `operation` closure.
- Throws: Throws an error if the operation fails or the system can’t run the operation.
Use this method to wrap long-running code in your app intent’s ``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.
While your operation runs, provide regular progress updates using the ``ProgressReportingIntent/progress``
property of the ``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 ``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.
```swift
func perform() async throws -> some IntentResult & ReturnsValue<String> {
let result = try await performBackgroundTask {
progress.totalUnitCount = 100
progress.localizedDescription = "Uploading file"
for chunk in 0..<100 {
try Task.checkCancellation()
await uploadChunk(chunk)
progress.completedUnitCount = Int64(chunk + 1)
progress.localizedAdditionalDescription = "\(chunk + 1)% complete"
}
return "Upload complete!"
}
return .result(value: result)
}
```
Skipped declarations
1 declarations were excluded from these bindings. Each reason comes from the generator or the iOS SDK compiler.
The iOS SDK compiler rejected this binding: instance method 'performBackgroundTask(options:operation:onCancel:)' requires that 'Self' conform to 'CancellableIntent'