问题
I'm using an NSURLSession
object to load images in my application. That could be loading several images simultaneously.
In some moments I need to cancel the loading of one specific image and continue loading others.
Could you suggest the correct way to do that?
回答1:
To get tasks list you can use NSURLSession's method
- (void)getTasksWithCompletionHandler:(void (^)(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks))completionHandler;
Asynchronously calls a completion callback with all outstanding data, upload, and download tasks in a session.
Then check task.originalRequest.URL
for returned tasks to find the one you want to cancel.
回答2:
Hope below code help.
-(IBAction)cancelUpload:(id)sender {
if (_uploadTask.state == NSURLSessionTaskStateRunning) {
[_uploadTask cancel];
}
}
回答3:
Swift 3.0 version of @Avt's answer to get the task list. Use getTasksWithCompletionHandler.
func getTasksWithCompletionHandler(_ completionHandler: @escaping ([URLSessionDataTask],
[URLSessionUploadTask],
[URLSessionDownloadTask]) -> Void) {
}
The returned arrays contain any tasks that you have created within the session, not including any tasks that have been invalidated after completing, failing, or being cancelled.
回答4:
I suggest two methods:
- Put the list of
NSURLSessionTask
in an array. In case you don't know exactly how many images you would get. Though you have to know the index of session in order to cancel it. - If you get a limited number of images. Just use a set of
NSURLSessionTask
as global variables so you can access to cancel it anywhere in your class.
回答5:
Based on all the answers below, I'd go for something like this:
Swift 5
func cancelTaskWithUrl(_ url: URL) {
URLSession.shared.getAllTasks { tasks in
tasks
.filter { $0.state == .running }
.filter { $0.originalRequest?.url == url }.first?
.cancel()
}
}
You also probably want to account for your task completion handler, since canceling the task will result Error
in that completion handler.
回答6:
I think you should do this...
First, keep track of your requests per xib
var download_requests = [NSURLSession]()
Then, whenever you make a request, append your request to your array like so,
let s = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
if let url = NSURL(string: "http://my.url.request.com")
{
download_requests.append(s)
s.dataTaskWithURL(url)
{ (data, resp, error) -> Void in
// ....
}
}
Then whenever you want to cancel any outstanding requests, (let's say on viewDidDisappear), do
override func viewDidDisappear(animated: Bool)
{
super.viewDidDisappear(animated)
//stop all download requests
for request in download_requests
{
request.invalidateAndCancel()
}
}
来源:https://stackoverflow.com/questions/23518690/how-to-find-and-cancel-a-task-in-nsurlsession