SKY*_*ine 0 viewcontroller ios swift
我有一个带有按钮的viewController,允许用户从URL下载文件.为了保持我的代码清洁,我创建了一个从我的视图中调用的下载类.它工作正常但现在我想为用户提供有关下载的一些UI提示.
假设我有一个标签,我想在下载结束后将其文本更改为"已下载".应该怎么做?
这是我的代码:
FileViewController
@IBOutlet weak var downloadLbl: UILabel!
func downloadFile(sender:UIButton!)
{
fileDownloader().download_zip(datastring, destination: path, name: naming, fileis: self.fileId)
}
Run Code Online (Sandbox Code Playgroud)
(这只是重要的部分)
然后我将我的下载功能放在一个单独的类文件中,然后启动一个DownloadTaskSession并使用以下委托来观察下载完成
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
println("session \(session) has finished the download task \(downloadTask) of URL \(location).")
FileViewController().downloadLbl.text = "downloaded"
}
Run Code Online (Sandbox Code Playgroud)
最后一行:FileViewController().downloadLbl.text = "downloaded"返回错误:致命错误:在展开Optional值时意外发现nil.
有人可以帮忙吗?
结论
这两个提议的解决方案在创建通信之间的通信时都有用,但是我去了通知解决方案,因为在我的情况下我必须更新UI以及后台线程进展并且使用协议不能按预期工作.进行了通信,但即使在使用dispatch_async方法推回主线程上的更改之后,更新UI仍无法正常工作.
使用通知系统有帮助,因为它更容易实现,管理和用于UI修改.
在这段代码中:
FileViewController().downloadLbl.text = "downloaded"
Run Code Online (Sandbox Code Playgroud)
您正在创建一个新的FileViewController,而不是引用现有的.这个新标签还没有标签,因为它的视图尚未构建.你参考downloadLbl,这是一个UILabel!.它是nil,所以你的应用程序崩溃.
我有一个单独的类文件中的下载功能
这是一个很好的做法,但是让这个单独的类修改UI是一种不好的做法.相反,你应该编写一个定义这些类如何交互的Swift协议.
一个简单的例子:
protocol MyAwesomeDownloadResponder : class {
func downloadFinished()
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在视图控制器中实现此方法:
class FileViewController : UIViewController, MyAwesomeDownloadResponder {
@IBOutlet weak var downloadLbl: UILabel!
func downloadFinished() {
downloadLbl.text = "Downloaded"
}
}
Run Code Online (Sandbox Code Playgroud)
在下载类中,存储一个引用responder,然后在下载完成时调用响应者:
class Downloader {
weak var responder : MyAwesomeDownloadResponder?
init(responder : MyAwesomeDownloadResponder) {
self.responder = responder
}
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
responder?.downloadFinished()
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要在这些类之间传递任何信息,请在中定义它protocol.