【问题标题】:Cancel NSURLSession if user taps twice in swift iOS如果用户在 swift iOS 中点击两次,则取消 NSURLSession
【发布时间】:2015-06-17 03:50:36
【问题描述】:

我使用的是 NSURLSession,根据这个线程是首选的。 How to make an HTTP request in Swift?

let url = NSURL(string: "http://www.stackoverflow.com")

let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
    println(NSString(data: data, encoding: NSUTF8StringEncoding))
}

task.resume()

我唯一的问题是当用户点击两次并且我想取消第一个请求时。我已经尝试过 task.cancel() 但打印语句仍在执行(即在带有 NSDomainError 的 .cancel() 之后)。如何在不触发打印语句的情况下安全地取消此请求(NSURLSessionDataTask),或者甚至有可能?

编辑: 只是要清楚。 URL 可能相同,我想取消第一个请求。

【问题讨论】:

  • print 语句或NSDomainError 是否指定任务已取消?如果是这样,只需打开它并忽略该错误,因为您期待它。
  • @LoVo 不,那是一个不同的问题(他在寻找任务时遇到了问题),我还询问了如何快速做到这一点。
  • @keithbhunter 我现在正在研究这个,似乎它可以用一种丑陋的方式解决。
  • 但是答案是正确的,把你的任务放在一个数组中,如果你想取消其中一个,检查状态。代码可能在 obj-c 中,但它应该很容易迁移。

标签: ios swift nsurlsession


【解决方案1】:

这就是我解决问题的方法。执行 task.cancel() 时,不会执行 print 语句。检查字符串似乎有点笨拙,所以如果有人有更好的解决方案,我会接受那个。

let url = NSURL(string: "http://www.stackoverflow.com")

let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
    if (error?.userInfo?["NSLocalizedDescription"] as? String) == "cancelled"
            {
                return
            }
    println(NSString(data: data, encoding: NSUTF8StringEncoding))
}

task.resume()

【讨论】:

  • 为了避免检查我所做的字符串:if let err = error as? NSURLError { if err == NSURLError.Cancelled { print("❌ 请求取消") } }
【解决方案2】:

我希望这是你可以使用的东西:

class ViewController: UIViewController , NSURLSessionDownloadDelegate {

    var download : NSURLSessionDownloadTask?
    var backgroundSession : NSURLSession?

    override func viewDidLoad() {
        super.viewDidLoad()

        let sessionConfiguration : NSURLSessionConfiguration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("CustomBackgroundIdentifier")
        backgroundSession = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: NSOperationQueue.mainQueue())

        var btn = UIButton(frame: CGRectMake(0, 0, 100, 100))
        btn.backgroundColor = UIColor.redColor()
        btn.addTarget(self, action: "startDownload", forControlEvents: UIControlEvents.TouchDown)
        self.view.addSubview(btn)

        var btn2 = UIButton(frame: CGRectMake(0, 120, 100, 100))
        btn2.backgroundColor = UIColor.blueColor()
        btn2.addTarget(self, action: "cancelDownload", forControlEvents: UIControlEvents.TouchDown)
        self.view.addSubview(btn2)

    }

    func startDownload() {
        if download == nil {
            if let url = NSURL(string: "http://www.stackoverflow.com") {
                download = backgroundSession?.downloadTaskWithURL(url)
                download?.resume()
            }
        } else {
            resumeDownload()
        }
    }

    func pauseDownload() {
        if download != nil {
            download?.suspend()
        }
    }

    func resumeDownload() {
        if download != nil {
            download?.resume()
        }
    }

    func cancelDownload() {
        if download != nil {
            download?.cancel()
        }
    }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
        println("Session %@ download task %@ finished downloading to URL %@\n",
        session, downloadTask, location)
    }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        println("downloaded: %i",totalBytesWritten)
    }
}

【讨论】:

  • 您是否应该使用download!.resume() 而不是download?.resume()(和其他),因为您已经将其包裹在nil 支票中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多