正在等待异步下载

时间:2017-01-23 22:52:48

标签: swift asynchronous download nsoperation nsoperationqueue

在我下载mp3文件的NSOperation中,我使用NSURLSession进行下载。我还使用NSURLSessionDownloadDelegate来检查我的进度。我需要使用NSOperationQueue.maxConcurrentOperationCount,但在我的情况下,操作的completionBlock将立即执行,因为NSURLSession是异步任务。因此,在下载完成之前,NSOperationQueue中的operationsCount将为0。我怎么能举行NSURLSession?

我的NSOperaton课程:

class DownloadManager: NSOperation
{
    private var internetTask : NSURLSessionTask?
    var track : TrackModel
    var didStartDownload : () -> Void
    var downloadFailure : () -> Void
    var didEndDownload : () -> Void
    weak var progress : KDCircularProgress!

init(withTrackModel trackModel : TrackModel,
                    withProgress progress : KDCircularProgress,
                    withDidStartDownloading didStartDownload : () -> Void,
                                            withDownloadFailure downloadFailure : () -> Void,
                                                                withDidEndDownloading didEndDownloading : ()->Void)
{
    self.track = trackModel
    self.didStartDownload = didStartDownload
    self.downloadFailure = downloadFailure
    self.didEndDownload = didEndDownloading
    self.progress = progress
}


override func cancel()
{
    super.cancel()

    LogManager.addStringToLog(withText: "Download task cancelled")
    internetTask?.cancel()
    track.downloadManager = nil
    downloadFailure()
}


override func main()
{
    if !self.cancelled
    {
        track.downloadManager = self

        if let audioUrl = NSURL(string: track.url!)
        {
            if let localUrl = AudioSaver.getFileLocalPathByUrl(audioUrl)
            {
                LogManager.addStringToLog(withText: "The file already exists at path: \(localUrl)")
                track.isDownloaded = true
                track.downloading = false
                track.localURL = localUrl.absoluteString
                addTrackToDataBase()
                track.downloadManager = nil
                self.didEndDownload()
            }

            let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: self, delegateQueue: nil)
            internetTask = session.downloadTaskWithURL(audioUrl)

            track.downloading = true
            self.didStartDownload()
            internetTask!.resume()
        }
    }
    else
       {
        LogManager.addStringToLog(withText: "Download task was cancelled while started download track \(track.title)")
        track.downloadManager = nil
        downloadFailure()
       }
    }
}


//MARK: - NSURLSessionDelegate
extension DownloadManager: NSURLSessionDownloadDelegate
{
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64)
    {
        LogManager.addStringToLog(withText: "download task did resume")
    }


func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL)
{
    if !self.cancelled
    {
        let audioUrl = downloadTask.originalRequest!.URL

        if let data = NSData(contentsOfURL: location)
        {
            AudioSaver.storeFileLocally(audioUrl!, data: data, track: track)

            dispatch_async(dispatch_get_main_queue())
            {
                LogManager.addStringToLog(withText: "download task did finish")
                self.addTrackToDataBase()
                self.track.downloadManager = nil
                self.didEndDownload()
            }
        }
        else
        {
            LogManager.addStringToLog(withText: "Error while saving track \(track.title)")
            self.track.downloadManager = nil
            self.downloadFailure()
        }
    }
    else
    {
        LogManager.addStringToLog(withText: "Download task cancelled while saving track \(track.title)")
        self.track.downloadManager = nil
        downloadFailure()
    }

}


func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
{
    if !self.cancelled
    {
        let progress = (Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)) * 100

        dispatch_async(dispatch_get_main_queue(), {
            self.progress.angle = Double(progress) * 3.6
        })
    }
    else
    {
        LogManager.addStringToLog(withText: "Download task cancelled while downloading track \(track.title)")
    }
}


func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
{
    if error != nil
    {
        LogManager.addStringToLog(withText: "Error while downloading track \(self.track.title). Error code is \(error!.code) == \(error!.localizedDescription)")
        self.cancel()
    }

}
}

0 个答案:

没有答案