2015-09-26 72 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