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
Другие вопросы по тегам