2015-09-26 73 views
0

我的应用程序同时下载多个文件。我的场景如下:swift iOS - NSURLSession没有正确下载多个文件

  1. 用户单击下载按钮。
  2. 下载UITableViewCell初始化,实现NSURLSessionDelegate以下载指定文件。
  3. 开始下载。下载单元显示正在使用NSURLSession提供的委托下载文件时的进度。
  4. 该文件在本地保存在文档文件夹中。
  5. 用户单击一个按钮清除所有完成的下载。此按钮清除Download Cell使用的数组'downloadQueue'。该按钮还调用tableView.reloadData来更新tableView

问题是,当用户启动多个下载时,没有问题发生。所有文件同时正确下载。但是,当用户单击第5步中描述的按钮,然后尝试下载另一个文件时,下载进度立即显示100%完成。并没有文件保存在本地。这可能是由于didFinishDownloadingToURL被立即调用。

这里是我的DownloadCell.swift

class DownloadCell: UITableViewCell, NSURLSessionDelegate { 


@IBOutlet weak var lblSongName: UILabel! 
@IBOutlet weak var progressBar: UIProgressView! 
@IBOutlet weak var progressCount: UILabel! 

var song: Song! 

var task: NSURLSessionTask! 

var percentageWritten: Float = 0.0 
var taskTotalBytesWritten = 0 
var taskTotalBytesExpectedToWrite = 0 

lazy var session: NSURLSession = { 
    let config = NSURLSessionConfiguration.ephemeralSessionConfiguration() 
    config.allowsCellularAccess = false 
    let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) 
    return session 
    }() 


override func awakeFromNib() { 
    super.awakeFromNib() 
    // Initialization code 

    } 

func startDownload() { 

    lblSongName.text = song.songName 

    if self.task != nil { 
     return 
    } 
    let url = NSURL(string: song.songDownloadLink)! 
    let req = NSMutableURLRequest(URL: url) 
    let task = self.session.downloadTaskWithRequest(req) 
    self.task = task 
    task.resume() 

} 

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) { 
    taskTotalBytesWritten = Int(writ) 
    taskTotalBytesExpectedToWrite = Int(exp) 
    percentageWritten = Float(taskTotalBytesWritten)/Float(taskTotalBytesExpectedToWrite) 
    progressBar.progress = percentageWritten 
    progressCount.text = String(Int(percentageWritten*100)) + "%" 

    print("(\(taskTotalBytesWritten)/\(taskTotalBytesExpectedToWrite))") 
} 

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 
    if error != nil { 
     print("Completed with error: \(error)") 
    } 
} 

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { 

    do { 
    let documentsDirectoryURL = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL! 
    progressCount.text = "Done!" 
    progressBar.progress = 100.0 

    try NSFileManager().moveItemAtURL(location, toURL: documentsDirectoryURL.URLByAppendingPathComponent(song.songName + ".mp3")) 

     //Handling Badge Values 
     let tabBar = UIApplication.sharedApplication().keyWindow?.rootViewController as! UITabBarController 
     let downloadVC = tabBar.viewControllers?[1] as! DownloadViewController 
     let badgeValue = Int(downloadVC.tabBarItem.badgeValue!)! - 1 
     downloadVC.tabBarItem.badgeValue = String(badgeValue) 

     if badgeValue == 0 { 
      downloadVC.tabBarItem.badgeValue = nil 
     } 

    } catch { 
     print("Error occurred during saving.") 
     progressCount.text = String(error) 

    } 

} 

}

回答

0

也许你应该实现prepareForReuse FUNC的UITableViewCell的完整代码?如果这些单元格被重用,它们仍然可能有任务,所以startDownload在开始处返回。此外,进度条的值不会重置为0.

+0

单元格正在重新使用。我不明白为什么设置进度栏值为零与任何事情有关,因为文件甚至没有被下载。让我感到困惑的是,当文件连续下载时,它工作得很好。此问题仅在阵列被清除然后重新填充时才存在。另外,你能解释一下实现prepareForReuse吗? – krypton36

+0

在startdownload函数的第5行放置了一个断点。 (在“return”行) – Vlk

+0

第5步之后,代码应该运行到您的断点。因为你说过使用tableView.reloadData来更新tableView。但reloadData使用dequeueReusableCellWithIdentifier调用cellForRowAtIndexpath,使用之前的单元格来制作单元格。这些单元没有被重新初始化,这就是单元重用的要点。所以他们的任务可能仍然不是零。你应该在prepareForReuse(最重要的任务,但progressbar.progress,progressCount.text等)中重置你想要的属性 – Vlk