krypton36
krypton36

Reputation: 317

swift iOS - NSURLSession not downloading multiple files properly

My App downloads multiple files at the same time. My scenario is as follows:

  1. The user clicks a download button.
  2. A Download UITableViewCell is initialized that implements NSURLSessionDelegate to download the specify file.
  3. A download is started. The Download Cell shows progress as the file is being downloaded using the provided Delegates by NSURLSession.
  4. The file is saved locally in the documents folder.
  5. The user clicks a button the clears all the finished downloads. This button clears the array 'downloadQueue' that Download Cell uses. The button also calls tableView.reloadData to update the tableView

The problem is, when the user initiates multiple downloads, no problem occurs. All files download properly simultaneously. However when the user clicks the button described in step 5, and then tries to download another file, the download progress shows 100% completed immediately. And no file is saved locally. This is probably due to didFinishDownloadingToURL being called immediately.

Here is the complete code of my 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)

    }

}

}

Upvotes: 0

Views: 1202

Answers (1)

Vlk
Vlk

Reputation: 99

Maybe you should implement the prepareForReuse func of uitableviewcell? If these cells are being reused, they still might have a task, so startDownload returns at the beginning. Also the progressbar's value is not resetted to 0.

Upvotes: 0

Related Questions