在downloadTask完成后执行segue

时间:2017-03-24 18:35:30

标签: ios swift swift3

我正在构建一个应用程序,一旦它连接到特定的本地网络,它会显示一个活动指示器然后开始下载图像的zip文件,一旦图像下载它解压缩文件,停止指示器然后执行segue到下一个View控制器。我有所有功能,但不知道如何在功能完成时观察。我的Donloader类看起来像这样:

class Downloader {

    let documentsUrl: URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!

    required init() {

        self.load()
    }

    func load() {

        // Create destination URL
        let destinationFileUrl = documentsUrl.appendingPathComponent("Images.zip")

        //Create URL to the source file you want to download
        let fileURL = URL(string: "http://127.0.0.1:4567/download")//FIXME for production

        //Create Session
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig)
        let request = URLRequest(url:fileURL!)

        let task = session.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, to: destinationFileUrl)
                } catch (let writeError) {

                    print("Error creating a file \(destinationFileUrl) : \(writeError)")
                }

            } else {

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

我的File类中的解压缩函数如下所示:

func unZip() {


    let zipFileURL = documentsURL?.appendingPathComponent("Images.zip")

    SSZipArchive.unzipFile(atPath: (zipFileURL?.path)!, toDestination: (documentsURL?.path)!)

    var directoryContents = [URL]()

    do {
        // Get the directory contents urls (including subfolders urls)
        directoryContents = try fileManager.contentsOfDirectory(at: documentsURL!, includingPropertiesForKeys: nil, options: [])
    } catch let error as NSError {

        print(error.localizedDescription)
    }

    let pngFiles = directoryContents.filter{ $0.pathExtension == "png" }//FIXME change file types if needed

    imageNamesArray = pngFiles.map{ $0.deletingPathExtension().lastPathComponent }
}

我已经看过闭包但不明白如何从类外或其他ViewController调用它们。任何帮助都会非常感谢。

2 个答案:

答案 0 :(得分:1)

添加没有返回值的完成处理程序非常简单。将load方法更改为

func load(finished: @escaping ()->()) 

在任务结束时调用finished()

  let task = session.downloadTask(with: request) { ...

     finished()
  }

并以这种方式致电load()

load() {
  // task has finished
}

但是使用完成处理程序,您应该删除required init并分别致电initload

答案 1 :(得分:0)

您可以尝试在Downloader类中存储完成闭包。

class Downloader {

    let documentsUrl: URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
    let completion: (Bool) -> ()
    required init(withCompletion completion: @escaping (Bool) -> ()) {
        self.completion = completion
        self.load()
    }

    func load() {

        // Create destination URL
        let destinationFileUrl = documentsUrl.appendingPathComponent("Images.zip")

        //Create URL to the source file you want to download
        let fileURL = URL(string: "http://127.0.0.1:4567/download")//FIXME for production

        //Create Session
        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig)
        let request = URLRequest(url:fileURL!)

        let task = session.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, to: destinationFileUrl)
                    self.completion(true)
                } catch (let writeError) {
                    self.completion(false)
                    print("Error creating a file \(destinationFileUrl) : \(writeError)")
                }

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

还以解压缩方法完成闭包。

func unZip(completion: (Bool) -> ()) {

        let zipFileURL = documentsURL?.appendingPathComponent("Images.zip")

        SSZipArchive.unzipFile(atPath: (zipFileURL?.path)!, toDestination: (documentsURL?.path)!)

        var directoryContents = [URL]()

        do {
            .. Get the directory contents urls (including subfolders urls)
            directoryContents = try fileManager.contentsOfDirectory(at: documentsURL!, includingPropertiesForKeys: nil, options: [])
        } catch let error as NSError {

            print(error.localizedDescription)
            completion(false)
        }

        let pngFiles = directoryContents.filter{ $0.pathExtension == "png" }//FIXME change file types if needed

        imageNamesArray = pngFiles.map{ $0.deletingPathExtension().lastPathComponent }
        completion(true)
    }

初始化Downloader,如下所示。

let downloader = Downloader { (success) in
    if success {
    let unzip = UnZip()
        unzip.unZip(completion: { (unzipSuccess) in
            if unzipSuccess {
                DispatchQueue.main.async {
                    //Stop Loading Indicator
                    //Perform Segue
                }

            }
        })
    }
}