import Foundation class FileDownloader: NSObject, URLSessionDownloadDelegate { private var completion: ((URL?, Error?) -> Void)? func downloadFile(from url: URL, completion: @escaping (URL?, Error?) -> Void) { self.completion = completion let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) let task = session.downloadTask(with: url) task.resume() } // MARK: - URLSessionDownloadDelegate func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { let destinationURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString) do { try FileManager.default.moveItem(at: location, to: destinationURL) DispatchQueue.main.async { self.completion?(destinationURL, nil) } } catch { DispatchQueue.main.async { self.completion?(nil, error) } } } func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { DispatchQueue.main.async { self.completion?(nil, error) } } } }