iosnsurlsessiondownloadtaskurlsession

urlsession how to determine when all files are downloaded


I am downloading a few files from a server using an urlsession, the delegate "didFinishDownloadingTo" is triggered after each download. But I would like something that trigger after all the downloads are completed.

is the delegate "didCompleteWithError" that I have to use?

how can I know if all files have been downloaded?

func downloadPdf() {

    for k in self.resultAddressServer {


            let fileURL = URL(string: k)
            let sessionConfig = URLSessionConfiguration.default
            let operationQueue = OperationQueue()
            let urlSession = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: operationQueue)
            let request = URLRequest(url:fileURL!)
            let downloadTask = urlSession.downloadTask(with: request)

            downloadTask.resume()
    }
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {

    do {
        let manager = FileManager.default
        let destinationURL = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            .appendingPathComponent(downloadTask.originalRequest!.url!.lastPathComponent)
        try? manager.removeItem(at: destinationURL)
        try manager.moveItem(at: location, to: destinationURL)
        print(destinationURL)
    } catch {
        print(error)
    }

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    if error != nil {
        DispatchQueue.main.async() {
            self.statusLabel.text = "Download failed"
        }
} else {
        DispatchQueue.main.async() {
            self.statusLabel.text = "Download finished"

        }
}

Solution

  • Following suggestions from other posts, I have added an array where I add the downloadTask identifier number, then in the delegate I remove the that identifier # when the task is complete. In the end to know if all downloads are completed, I just check when the array.count is equal to 0.

    func downloadPdf() {
    
        for k in self.resultAddressServer {
    
    
                let fileURL = URL(string: k)
                let sessionConfig = URLSessionConfiguration.background(withIdentifier: "com.Test")
                let urlSession = URLSession(configuration: sessionConfig, delegate: self, delegateQueue: OperationQueue())
                let request = URLRequest(url:fileURL!)
                let downloadTask = urlSession.downloadTask(with: request)
                self.tasksArray.append(downloadTask.taskIdentifier)
                print(downloadTask.taskIdentifier)
                downloadTask.resume()
        }
    
    
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    
        do {
            let manager = FileManager.default
            let destinationURL = try manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
                .appendingPathComponent(downloadTask.originalRequest!.url!.lastPathComponent)
            try? manager.removeItem(at: destinationURL)
            try manager.moveItem(at: location, to: destinationURL)
            print(destinationURL)
        } catch {
            print(error)
        }
    
        if let index = self.tasksArray.index(of: downloadTask.taskIdentifier) {
            self.tasksArray.remove(at: index)
            print(self.tasksArray.count)
        }
    
        DispatchQueue.main.async() {
    
            if self.tasksArray.count == 0 {
    
                //Do whatever you want, all downloads are completed
                //the DispatchQueue is for what I use this for...maybe not needed in you case
            }
    
    
        }
    }