Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check the current progress of URLSession.dataTaskPublisher?

Tags:

swift

combine

I'm using a dataTaskPublisher to fetch some data:

func downloadData(_ req: URLRequest) {
  self.cancelToken = dataTaskPublisher(for: req).sink { /* ... */ }
}

If the function is called while the request is in progress, I would like to return.

Currently I either:
1. Set the cancelToken to nil in the sink or
2. Crate and manage a isDownloading variable.

Is there a built-in way to check if the dataTaskPublisher is running (and optionally its progress)?

like image 880
chustar Avatar asked Apr 08 '20 14:04

chustar


People also ask

What will happend if you don't invalidate the session URLSession explicitly?

If you don't invalidate the session, your app leaks memory until the app terminates. Each task you create with the session calls back to the session's delegate, using the methods defined in URLSessionTaskDelegate .

What is API or have you used URLSession Class What does it do?

The URLSession is used to create URLSessionTask instances, which can fetch and return data to your app, and download and upload files to webservices. You configure a session with a URLSessionConfiguration object. This configuration manages caching, cookies, connectivity and credentials.


2 Answers

I mostly agree with @Rob, however you can control state of DataTask initiated by DataTaskPublisher and its progress by using of URLSession methods:

func downloadData(_ req: URLRequest) {
    URLSession.shared.getAllTasks { (tasks) in
        let task = tasks.first(where: { (task) -> Bool in
            return task.originalRequest?.url == req.url
        })

        switch task {
        case .some(let task) where task.state == .running:
            print("progress:", Double(task.countOfBytesReceived) / Double(task.countOfBytesExpectedToReceive))
            return
        default:
            self.cancelToken = URLSession.shared.dataTaskPublisher(for: req).sink { /* ... */ }
        }
    }
}
like image 183
Denis Kreshikhin Avatar answered Oct 24 '22 20:10

Denis Kreshikhin


Regarding getting progress from this publisher, looking at the source code, we can see that it’s just doing a completion-block-based data task (i.e. dataTask(with:completionHandler:)). But the resulting URLSessionTask is a private property of the private Subscription used by DataTaskPublisher. Bottom line, this publisher doesn’t provide any mechanism to monitor progress of the underlying task.

As Denis pointed out, you are limited to querying the URLSession for information about its tasks.

like image 36
Rob Avatar answered Oct 24 '22 22:10

Rob