Swift - Как узнать, когда файл успешно загружен с URL, используя FileManager.default.copyItem
У меня есть сценарий, в котором я должен загрузить ZIP-файл с URL-адреса и после завершения загрузки мне нужно распаковать его в асинхронном режиме. Проблема здесь в том, что FileManager.default.copyItem занимает некоторое время, поэтому я не могу сразу распаковать файл. Ниже приведен код для загрузки zip-файла:
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()
}
Будучи новичком, я хочу знать, есть ли в swift любой обратный вызов, который может сказать мне, что файл загружен и доступен для распаковки. Я использую библиотеку SSZipArchive для распаковки файла.
ниже приведен код для распаковки
SSZipArchive.unzipFile(atPath: path, toDestination: destinationpath)
1 ответ
URLSession работает с двумя видами механизмов обратного вызова:
- Обработчик завершения - это то, что использует ваш код
- URLSession делегаты
Чтобы конкретно ответить на ваш вопрос, обработчик завершения, который вы написали в приведенном выше коде, будет вызван после завершения загрузки. В качестве альтернативы, если вы хотите сделать то же самое в методе делегата, код должен выглядеть примерно так:
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