我正在构建一个应用程序,一旦它连接到特定的本地网络,它会显示一个活动指示器然后开始下载图像的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调用它们。任何帮助都会非常感谢。
答案 0 :(得分:1)
添加没有返回值的完成处理程序非常简单。将load
方法更改为
func load(finished: @escaping ()->())
在任务结束时调用finished()
let task = session.downloadTask(with: request) { ...
finished()
}
并以这种方式致电load()
load() {
// task has finished
}
但是使用完成处理程序,您应该删除required init
并分别致电init
和load
。
答案 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
}
}
})
}
}