How does one deal with a cancelled NSURLSessionTask in the completion handler block?

Doug Smith picture Doug Smith · Oct 16, 2014 · Viewed 20.7k times · Source

If I create a NSURLSessionDownloadTask, and later cancel it before it finishes, the completion block still fires seemingly.

let downloadTask = session.downloadTaskWithURL(URL, completionHandler: { location, response, error in 
    ...
}

How do I check whether or not the download task was cancelled within this block so that I don't try to operate on the resulting download when there isn't one?

Answer

Rob picture Rob · Oct 16, 2014

For download task, the completion handler will be called with nil value for the location and the code value of the NSError object will be NSURLErrorCancelled. For example:

let task = session.downloadTask(with: url) { location, response, error in
    if let error = error as NSError? {
        if error.code == NSURLErrorCancelled {
            // canceled
        } else {
            // some other error
        }
        return
    }
    
    // proceed to move file at `location` to somewhere more permanent
}
task.resume()

Likewise for data tasks, the completion handler will be called with a Error/NSError that indicates whether it was canceled. For example:

let task = session.dataTask(with: url) { data, response, error in
    if let error = error as NSError? {
        if error.code == NSURLErrorCancelled {
            // canceled
        } else {
            // some other error
        }
        return
    }
    
    // proceed to move file at `location` to somewhere more permanent
}
task.resume()

For Swift 2, see previous revision of this answer.