URLSessionDownloadTask

URLSessionDownloadTask represents a background download task created by BackgroundURLSession.startDownload() or BackgroundURLSession.resumeDownload(). It allows scripts in the Scripting app to download files in the foreground or background, and the task can continue even if the script is terminated or the app is suspended.

Each download task is managed by the system and provides detailed state, progress, and event callbacks.


Properties

id: string

A unique identifier for the download task. You can use this ID to recognize or reattach to the same task when your script restarts.

Example

1console.log(task.id) // Prints the unique task ID

state: URLSessionTaskState

The current state of the task.

Possible values:

  • "running" — The task is currently downloading.
  • "suspended" — The task is paused.
  • "canceling" — The task is being canceled.
  • "completed" — The task has finished.
  • "unknown" — The state is unknown (usually when the task has been removed by the system).

Example

1if (task.state === "running") {
2  console.log("Download in progress…")
3}

progress: URLSessionProgress

Real-time progress information for the task.

Contains the following fields:

  • fractionCompleted: number — Progress fraction between 0 and 1.
  • totalUnitCount: number — Total number of bytes to download.
  • completedUnitCount: number — Number of bytes downloaded so far.
  • isFinished: boolean — Whether the task has completed.
  • estimatedTimeRemaining: number | null — Estimated remaining time (in seconds), or null if unknown.

Example

1const p = task.progress
2console.log(`Completed ${(p.fractionCompleted * 100).toFixed(2)}%`)

priority: number

The priority of the download task (range: 0.0–1.0). Defaults to 0.5. Higher values increase the likelihood that the system will prioritize this task.

Example

1task.priority = 0.8

earliestBeginDate?: Date | null

The earliest date when the download task is allowed to begin. Useful for delaying downloads or optimizing bandwidth usage.

Example

1task.earliestBeginDate = new Date(Date.now() + 10_000) // start after 10 seconds

countOfBytesClientExpectsToSend: number

A best-guess upper bound on the number of bytes expected to send (for system estimation only).

countOfBytesClientExpectsToReceive: number

A best-guess upper bound on the number of bytes expected to receive (for system estimation only).


Callbacks

onProgress?: (details) => void

Called periodically as the download progresses.

details includes:

  • progress: number — Progress fraction between 0 and 1.
  • bytesWritten: number — Bytes written since the last update.
  • totalBytesWritten: number — Total bytes downloaded so far.
  • totalBytesExpectedToWrite: number — Total expected bytes for the download.

Example

1task.onProgress = details => {
2  console.log(`Download progress: ${(details.progress * 100).toFixed(1)}%`)
3}

onFinishDownload?: (error, details) => void

Called when the download finishes (successfully or with an error).

Parameters

  • error: Error | null — Error object if the download failed, otherwise null.
  • details.temporary: string — The temporary file path used by the system.
  • details.destination: string | null — The final destination path (if successful) or null if the download failed.

The downloaded file is automatically moved to the specified destination path upon completion.

Example

1task.onFinishDownload = (error, details) => {
2  if (error) {
3    console.error("Download failed:", error)
4  } else {
5    console.log("Download completed at:", details.destination)
6  }
7}

onComplete?: (error, resumeData) => void

Called when the task finishes completely (either successfully or unsuccessfully).

Parameters

  • error: Error | null — Error object if the download failed, otherwise null.
  • resumeData: Data | null — Resume data available if the download can be resumed later.

Example

1task.onComplete = (error, resumeData) => {
2  if (error) {
3    console.error("Download error:", error)
4    if (resumeData) {
5      console.log("Resume data is available for resuming the download")
6    }
7  } else {
8    console.log("Download completed successfully")
9  }
10}

Methods

suspend(): void

Suspends the download task. While suspended, the task produces no network activity and is not subject to timeouts. You can later call resume() to continue.

Example

1task.suspend()
2console.log("Task suspended")

resume(): void

Resumes a suspended task. Call this only if the task is in a "suspended" state.

Example

1task.resume()
2console.log("Task resumed")

cancel(): void

Cancels the download task immediately. The task enters the "canceling" state, and the onComplete callback is triggered with an error once cancellation finishes.

Example

1task.cancel()
2console.log("Task canceled")

cancelByProducingResumeData(): Promise<Data | null>

Cancels the download task and attempts to produce resume data. If resumable, the returned promise resolves to Data which can be used later with BackgroundURLSession.resumeDownload(). Otherwise, it resolves to null.

Example

1const resumeData = await task.cancelByProducingResumeData()
2if (resumeData) {
3  console.log("Download canceled; resume data available for later resumption")
4}

Example Usage

1const task = BackgroundURLSession.startDownload({
2  url: "https://example.com/largefile.zip",
3  destination: "/.../Downloads/largefile.zip",
4  notifyOnFinished: true
5})
6
7task.onProgress = ({ progress }) => {
8  console.log(`Progress: ${(progress * 100).toFixed(1)}%`)
9}
10
11task.onFinishDownload = (error, details) => {
12  if (error) {
13    console.error("Download failed:", error)
14  } else {
15    console.log("Download completed at:", details.destination)
16  }
17}
18
19task.onComplete = async (error, resumeData) => {
20  if (error && resumeData) {
21    console.log("Resume data available — save it to resume later")
22  }
23}

Notes and Best Practices

  • You need to call resume() start the download when you create a task by BackgroundURLSession.startDownload().
  • Use cancelByProducingResumeData() to implement download resumption.
  • Even if the script exits or is terminated, downloads continue in the background.
  • After restarting the script, use BackgroundURLSession.getDownloadTasks() to recover existing tasks and reattach callbacks.
  • For long-running tasks, use notifyOnFinished to inform the user when a download completes.