问题
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.
below is code for unzipping it using
SSZipArchive.unzipFile(atPath: path, toDestination: destinationpath)
回答1:
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
来源:https://stackoverflow.com/questions/46640161/swift-how-to-know-when-the-file-is-successfully-download-from-url-using-filema