Swift Filemanager [work] Download File Online
For large files like videos or zip archives, users expect a visual progress bar. The basic async/await method wrapper does not stream progress. To capture progress updates, use a URLSessionDownloadDelegate .
If a file with the same name exists at the destination path, FileManager.moveItem will throw an error and fail. Explicitly check for existence and use FileManager.removeItem first.
Are you dealing with while the app is closed? swift filemanager download file
import Foundation enum DownloadError: Error { case invalidURL case missingDestination } class FileDownloadManager { /// Downloads a file from a URL and saves it to the Documents directory /// - Parameters: /// - urlString: The remote file URL string /// - customFileName: Optional custom name for the saved file /// - Returns: The local URL where the file was saved func downloadAndSaveFile(from urlString: String, customFileName: String? = nil) async throws -> URL { // 1. Validate the remote URL guard let remoteURL = URL(string: urlString) else { throw DownloadError.invalidURL } // 2. Perform the download using URLSession // This returns a temporary local file URL and the network response let (tempLocalURL, _) = try await URLSession.shared.download(from: remoteURL) // 3. Determine the target directory (Documents Directory) let fileManager = FileManager.default let documentDirectories = fileManager.urls(for: .documentDirectory, in: .userDomainMask) guard let documentsDirectory = documentDirectories.first else { throw DownloadError.missingDestination } // 4. Determine the final file name let fileName = customFileName ?? remoteURL.lastPathComponent let destinationURL = documentsDirectory.appendingPathComponent(fileName) // 5. Clean up existing files if necessary if fileManager.fileExists(atPath: destinationURL.path) { try fileManager.removeItem(at: destinationURL) } // 6. Move the file from the temporary location to the final destination try fileManager.moveItem(at: tempLocalURL, to: destinationURL) return destinationURL } } Use code with caution. How to use this service:
Here is a complete guide on how to safely download files, locate the correct directories, and write data to disk using Swift. 📂 1. Understanding the Sandbox and Target Directories For large files like videos or zip archives,
import Foundation class ProgressDownloadManager: NSObject, URLSessionDownloadDelegate { private var session: URLSession! var onProgress: ((Double) -> Void)? var onCompletion: ((URL?, Error?) -> Void)? override init() { super.init() // Create a custom session configuration to attach the delegate let configuration = URLSessionConfiguration.default self.session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) } func startDownload(from urlString: String) { guard let url = URL(string: urlString) else { return } let downloadTask = session.downloadTask(with: url) downloadTask.resume() } // MARK: - URLSessionDownloadDelegate // 1. Tracks bytes written to calculate percentage func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) DispatchQueue.main.async { self.onProgress?(progress) } } // 2. Triggered when the download finishes entirely func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { let fileManager = FileManager.default let destination = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0] .appendingPathComponent(downloadTask.originalRequest?.url?.lastPathComponent ?? "downloaded_file") do { if fileManager.fileExists(atPath: destination.path) { try fileManager.removeItem(at: destination) } try fileManager.moveItem(at: location, to: destination) DispatchQueue.main.async { self.onCompletion?(destination, nil) } } catch { DispatchQueue.main.async { self.onCompletion?(nil, error) } } } } Use code with caution. 🔒 4. Best Practices for Production Apps
Apple enforces strict sandboxing rules on its platforms. Apps cannot write files anywhere they want. You must choose a specific container directory depending on the file type and purpose. If a file with the same name exists
Do you need to save to instead of the Sandbox?