Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用Swift取消队列中的下载_Ios_Swift_Nsoperation_Nsoperationqueue - Fatal编程技术网

Ios 如何使用Swift取消队列中的下载

Ios 如何使用Swift取消队列中的下载,ios,swift,nsoperation,nsoperationqueue,Ios,Swift,Nsoperation,Nsoperationqueue,我有一个应用程序,用户可以下载多个文件,顺序。我已经按照顺序下载了。然而,当我试图取消下载时,我遇到了问题 if cell.downloadLabel.currentTitle == "CANCEL" { print("cancel button was pressed") downloadManager.cancelAll() // I want to put the codes here let

我有一个应用程序,用户可以下载多个文件,顺序。我已经按照顺序下载了。然而,当我试图取消下载时,我遇到了问题

 if cell.downloadLabel.currentTitle == "CANCEL"
        {
            print("cancel button was pressed")

            downloadManager.cancelAll()

// I want to put the codes here

            let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
            let key = cell.stringId
            print("key : \(key)")
            defaults.setBool(false, forKey: key)
            defaults.synchronize()

            cell.accessoryType = UITableViewCellAccessoryType.None
            cell.downloadLabel.backgroundColor = UIColor.redColor()
            cell.downloadLabel.setTitle("DOWNLOAD", forState: .Normal)
        }
当我试图取消下载时,有两种情况

 if cell.downloadLabel.currentTitle == "CANCEL"
        {
            print("cancel button was pressed")

            downloadManager.cancelAll()

// I want to put the codes here

            let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
            let key = cell.stringId
            print("key : \(key)")
            defaults.setBool(false, forKey: key)
            defaults.synchronize()

            cell.accessoryType = UITableViewCellAccessoryType.None
            cell.downloadLabel.backgroundColor = UIColor.redColor()
            cell.downloadLabel.setTitle("DOWNLOAD", forState: .Normal)
        }
  • 我想取消当前下载的文件。当我取消该文件时,下载可以继续到队列中的下一个文件
  • 我想取消当前在队列中的文件。队列具有cancelAll()方法,该方法将取消队列中的所有文件
  • 这是密码

    下载管理器.swift

    class DownloadManager: NSObject, NSURLSessionTaskDelegate, NSURLSessionDownloadDelegate
    {
    
        /// Dictionary of operations, keyed by the `taskIdentifier` of the `NSURLSessionTask`
        internal var delegate : DownloadVC!
        private var operations = [Int: DownloadOperation]()
    
        /// Serial NSOperationQueue for downloads
    
        let queue: NSOperationQueue = {
            let _queue = NSOperationQueue()
            _queue.name = "download"
            _queue.maxConcurrentOperationCount = 1
            return _queue
        }()
    
        /// Delegate-based NSURLSession for DownloadManager
    
        lazy var session: NSURLSession = {
            let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
            return NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: nil)
        }()
    
        /// Add download
        ///
        /// - parameter URL:  The URL of the file to be downloaded
        ///
        /// - returns: The DownloadOperation of the operation that was queued
    
        func addDownload(URL: NSURL) -> DownloadOperation
        {
            print("url in download manager: \(URL)")
            let operation = DownloadOperation(session: session, URL: URL)
            operations[operation.task.taskIdentifier] = operation
            queue.addOperation(operation)
            return operation
        }
    
        /// Cancel all queued operations
    
        func cancelAll()
        {
            queue.cancelAllOperations()
    
        }
    
    //    func cancelOne()
    //    {
    //        operations[identifier]?.cancel()
    //        print("identifier : \(identifier)")
    //        //queue.operations[identifier].cancel()
    //       // cancelAll()
    //    }
    
        // MARK: NSURLSessionDownloadDelegate methods
    
        func URLSession(session: NSURLSession,
            downloadTask: NSURLSessionDownloadTask,
            didFinishDownloadingToURL location: NSURL)
        {
            print("downloadTask.taskIdentifier \(downloadTask.taskIdentifier)")
            operations[downloadTask.taskIdentifier]?.delegate = delegate
            operations[downloadTask.taskIdentifier]?.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
        }
    
        func URLSession(session: NSURLSession,
            downloadTask: NSURLSessionDownloadTask,
            didWriteData bytesWritten: Int64,
            totalBytesWritten: Int64,
            totalBytesExpectedToWrite: Int64)
        {
            operations[downloadTask.taskIdentifier]?.delegate = delegate
            operations[downloadTask.taskIdentifier]?.URLSession(session, downloadTask: downloadTask, didWriteData: bytesWritten, totalBytesWritten: totalBytesWritten, totalBytesExpectedToWrite: totalBytesExpectedToWrite)
        }
    
        // MARK: NSURLSessionTaskDelegate methods
    
        func URLSession(session: NSURLSession,
            task: NSURLSessionTask,
            didCompleteWithError error: NSError?)
        {
                let key = task.taskIdentifier
                operations[key]?.URLSession(session, task: task, didCompleteWithError: error)
                operations.removeValueForKey(key)
        }
    }
    
    下载操作.swift

    class DownloadOperation : AsynchronousOperation
    {
        let task: NSURLSessionTask
        var percentageWritten:Float = 0.0
        var delegate : DataDelegate!
    
        init(session: NSURLSession, URL: NSURL)
        {
            task = session.downloadTaskWithURL(URL)
            super.init()
        }
    
        override func cancel() {
            task.cancel()
            super.cancel()
        }
    
        override func main() {
            task.resume()
    
        }
    
        // MARK: NSURLSessionDownloadDelegate methods
    
            func URLSession(session: NSURLSession,
                downloadTask: NSURLSessionDownloadTask,
                didWriteData bytesWritten: Int64,
                totalBytesWritten write: Int64,
                totalBytesExpectedToWrite expect: Int64)
            {
                //download bar progress
                percentageWritten = Float(write) / Float(expect)
                //progressBar.progress = percentageWritten
                let pW = Int(percentageWritten*100)
                delegate.didWriteData(pW)
            }
    
            // using cocoa Security for encryption and decryption
            func URLSession(session: NSURLSession,
                downloadTask: NSURLSessionDownloadTask,
                didFinishDownloadingToURL location: NSURL)
            {
                let documentsDirectoryURL =  NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL?
                print("Finished downloading!")
                print(documentsDirectoryURL)
                let downloadLocation = "\(location)".stringByReplacingOccurrencesOfString("file://", withString: "")
    
                let fileData = NSFileManager().contentsAtPath(downloadLocation)
    
                delegate.didFinishDownloadingToUrl(fileData!)
            }
    
    
        // MARK: NSURLSessionTaskDelegate methods
    
        func URLSession(session: NSURLSession,
            task: NSURLSessionTask,
            didCompleteWithError error: NSError?)
        {
            completeOperation()
            if error != nil {
                print(error)
            }
        }
    }
    
    class AsynchronousOperation : NSOperation
    {
    
        override var asynchronous: Bool { return true }
    
        private var _executing: Bool = false
        override var executing: Bool
            {
            get
            {
                return _executing
            }
            set {
                if (_executing != newValue)
                {
                    self.willChangeValueForKey("isExecuting")
                    _executing = newValue
                    self.didChangeValueForKey("isExecuting")
                }
            }
        }
    
        private var _finished: Bool = false
        override var finished: Bool
            {
            get
            {
                return _finished
            }
            set
            {
                if (_finished != newValue)
                {
                    self.willChangeValueForKey("isFinished")
                    _finished = newValue
                    self.didChangeValueForKey("isFinished")
                }
            }
        }
    
        func completeOperation()
        {
            if executing {
                executing = false
                finished = true
            }
        }
    
        override func start()
        {
            if (cancelled) {
                finished = true
                executing = false
                return
            }
    
            executing = true
    
            main()
        }
    
    }
    
    AsynchronousOperation.swift

    class DownloadOperation : AsynchronousOperation
    {
        let task: NSURLSessionTask
        var percentageWritten:Float = 0.0
        var delegate : DataDelegate!
    
        init(session: NSURLSession, URL: NSURL)
        {
            task = session.downloadTaskWithURL(URL)
            super.init()
        }
    
        override func cancel() {
            task.cancel()
            super.cancel()
        }
    
        override func main() {
            task.resume()
    
        }
    
        // MARK: NSURLSessionDownloadDelegate methods
    
            func URLSession(session: NSURLSession,
                downloadTask: NSURLSessionDownloadTask,
                didWriteData bytesWritten: Int64,
                totalBytesWritten write: Int64,
                totalBytesExpectedToWrite expect: Int64)
            {
                //download bar progress
                percentageWritten = Float(write) / Float(expect)
                //progressBar.progress = percentageWritten
                let pW = Int(percentageWritten*100)
                delegate.didWriteData(pW)
            }
    
            // using cocoa Security for encryption and decryption
            func URLSession(session: NSURLSession,
                downloadTask: NSURLSessionDownloadTask,
                didFinishDownloadingToURL location: NSURL)
            {
                let documentsDirectoryURL =  NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL?
                print("Finished downloading!")
                print(documentsDirectoryURL)
                let downloadLocation = "\(location)".stringByReplacingOccurrencesOfString("file://", withString: "")
    
                let fileData = NSFileManager().contentsAtPath(downloadLocation)
    
                delegate.didFinishDownloadingToUrl(fileData!)
            }
    
    
        // MARK: NSURLSessionTaskDelegate methods
    
        func URLSession(session: NSURLSession,
            task: NSURLSessionTask,
            didCompleteWithError error: NSError?)
        {
            completeOperation()
            if error != nil {
                print(error)
            }
        }
    }
    
    class AsynchronousOperation : NSOperation
    {
    
        override var asynchronous: Bool { return true }
    
        private var _executing: Bool = false
        override var executing: Bool
            {
            get
            {
                return _executing
            }
            set {
                if (_executing != newValue)
                {
                    self.willChangeValueForKey("isExecuting")
                    _executing = newValue
                    self.didChangeValueForKey("isExecuting")
                }
            }
        }
    
        private var _finished: Bool = false
        override var finished: Bool
            {
            get
            {
                return _finished
            }
            set
            {
                if (_finished != newValue)
                {
                    self.willChangeValueForKey("isFinished")
                    _finished = newValue
                    self.didChangeValueForKey("isFinished")
                }
            }
        }
    
        func completeOperation()
        {
            if executing {
                executing = false
                finished = true
            }
        }
    
        override func start()
        {
            if (cancelled) {
                finished = true
                executing = false
                return
            }
    
            executing = true
    
            main()
        }
    
    }
    
    下载ViewController.swift

    这是我想取消下载的地方

     if cell.downloadLabel.currentTitle == "CANCEL"
            {
                print("cancel button was pressed")
    
                downloadManager.cancelAll()
    
    // I want to put the codes here
    
                let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
                let key = cell.stringId
                print("key : \(key)")
                defaults.setBool(false, forKey: key)
                defaults.synchronize()
    
                cell.accessoryType = UITableViewCellAccessoryType.None
                cell.downloadLabel.backgroundColor = UIColor.redColor()
                cell.downloadLabel.setTitle("DOWNLOAD", forState: .Normal)
            }
    
    对于情况1,我尝试使用do

    queue.operations[identifier].cancel()
    
    但是它说

    *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
    
    对于情况2,我尝试将所有下载的URL放入一个数组中,添加到队列中,单击cancel按钮后,它将cancelAll()队列,从队列中删除cancel,并将剩余的URL重新插入到数组中。然而,这是行不通的


    有人能帮我满足这两种情况吗?

    您需要保留对
    NSOperation
    实例的引用。然后您可以在其上调用
    cancel

    可能重复的