Swift – How to know when the file is successfully download from url using FileManager.default.copyItem

I have a scenario in which i have to download a zip file from url and once download completed i need to unzip it in async fashion. Problem here is FileManager.default.copyItem takes sometime therefore i cannot immediately unzip the file. below is code for downloading zip file :

   func saveZipFile(url: URL, directory: String) -> Void {
        let request = URLRequest(url: url)



        let task = URLSession.shared.downloadTask(with: request) { (tempLocalUrl, response, error) in
            if let tempLocalUrl = tempLocalUrl, error == nil {
                // Success
                if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                    print("Successfully downloaded. Status code: \(statusCode)")
                }

                do {
                   try FileManager.default.copyItem(at: tempLocalUrl as URL, to: FileChecker().getPathURL(filename: url.lastPathComponent, directory: directory))

                    print("sucessfully downloaded the zip file ...........")
                    //unziping it
                    //self.unzipFile(url: url, directory: directory)

                } catch (let writeError) {
                        print("Error creating a file  : \(writeError)")
                }


            } else {
                print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
            }
        }
        task.resume()
    }

Being a beginner i want to know is there is any callback available in swift which can tell me the file is downloaded and is available for unzipping. I am using SSZipArchive library for unzipping the file.

  • Creating zip files in ObjectiveC for iPhone
  • Can not compress dSyms
  • Undefined symbols for architecture armv7 SSZipArchive
  • How to download & unzip files on iOS
  • iPhone Unzip code
  • How to zip folders in iPhone SDK?
  • below is code for unzipping it using

       SSZipArchive.unzipFile(atPath: path, toDestination: destinationpath)
    

    Solutions Collect From Internet About “Swift – How to know when the file is successfully download from url using FileManager.default.copyItem”

    URLSession works with two kinds of callback mechanisms:

    • Completion handler – this is what your code is using
    • URLSession delegates

    To answer your question specifically, the completion handler that you have written in the code above will be invoked when the download is completed. Alternatively, if you want to do the same in a delegate method, the code should be something like this:

    import Foundation
    import Dispatch //you won't need this in your app
    
    public class DownloadTask : NSObject {
    
        var currDownload: Int64 = -1 
    
        func download(urlString: String) {
            let config = URLSessionConfiguration.default
            let session = URLSession(configuration: config, delegate: self,   delegateQueue: nil)
    
            let url = URL(string: urlString)
            let task = session.downloadTask(with: url!)
            task.resume()
        }
    }
    
    
    extension DownloadTask : URLSessionDownloadDelegate {
    
        //this delegate method is called everytime a block of data is received    
        public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64,
                           totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) -> Void {
            let percentage = (Double(totalBytesWritten)/Double(totalBytesExpectedToWrite)) * 100
            if Int64(percentage) != currDownload  {
                print("\(Int(percentage))%")
                currDownload = Int64(percentage)
            }
        }
    
        //this delegate method is called when the download completes 
        public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
            //You can copy the file or unzip it using `location`
            print("\nFinished download at \(location.absoluteString)!")
        }
    
    }
    
    let e = DownloadTask()
    e.download(urlString: "https://swift.org/LICENSE.txt")
    dispatchMain() //you won't need this in your app