More detail on .backgroundTask(.urlSession("isStormy")) shown at 11:50

In the slides at 11:50 the following code snippet is shown:

.backgroundTask(.urlSession("isStormy")) {
    // ...
}

Please could you explain what should be done in this block? The video just cuts off right after and seems like the explanation is missing. Thanks.

Post not yet marked as solved Up vote post of malc Down vote post of malc
1.5k views

Replies

I too wonder how do we get at the downloaded data from the background task?

The URLSessionDownloadTask documentation says that "Download tasks directly write the server’s response data to a temporary file…", but it does not explain how to find out where this file lives once the download is completed by the new SwiftUI backgroundTask API.

I would also really like to know this! All I can think of is getting all the tasks from the urlSession and iterating through them.

I ended up doing the below, which works but seems very fragile in case there is more than one download in progress for the URL session.

.backgroundTask(.urlSession("isStormy")) {
    let session = …  // A stored URL session, with the identifier "isStormy"
    session.getAllTasks { tasks in
        for task in tasks {
            if task.state == .suspended || task.state == .canceling { continue }
            // NOTE: It seems the task state is .running when this is called, instead of .completed as one might expect.
                
            if let dlTask = task as? URLSessionDownloadTask {
                if let url = dlTask.response?.url {
                    if let data = try? Data(contentsOf: url) {
                        // Parse the data here.
                    }
                }
            }
        }
    }
}

On a related note, in my use on iOS 16 beta 3, the new SwiftUI backgroundTask API only gets invoked about 65% of the time when I start a background download, as compared to 100% when using the URLSessionDownloadDelegate method below.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    if let data = try? Data(contentsOf: location) {
        // Parse the data here.
    }
}
  • How did you end-up making the code inside this being run, it doesn't work for me at all.

Add a Comment